DeqingSun / ch55xduino

An Arduino-like programming API for the CH55X
GNU Lesser General Public License v2.1
433 stars 85 forks source link

Timers with the Arduino IDE #42

Closed Vykynger closed 3 years ago

Vykynger commented 3 years ago

Hey, I am facing some trouble with the Timers in the Arduino IDE. When working with the CH55xTool my Code works, but with the Arduino IDE, it does not. However, I would like to use some of your libraries for example for printing into the Serial Monitor. Below there is an example code, that I could not get to run. It would be really nice if you could tell me what the problem is.


#define LED_PIN 7

SBIT(LED, 0x90, LED_PIN);
int counter = 0;
/**
SFR(TMOD,  0x89);  // timer 0/1 mode
SFR(TH0,  0x8C);  // high byte of timer 0 count
SFR(TL0,  0x8A);  // low byte of timer 0 count
SBIT(TR0,  0x88, 4); // timer0 run enable
SBIT(ET0,  0xA8, 1); // enable timer0 interrupt
SBIT(EA,  0xA8, 7); // enable global interrupts: 0=disable, 1=enable if E_DIS=0
**/
void setup() {
    //CfgFsys(); <-- from ch554.h
    // Configure pin 1.7 as GPIO output
    P1_DIR_PU &= 0x0C;
    P1_MOD_OC = P1_MOD_OC & ~(1<<LED_PIN);
    P1_DIR_PU = P1_DIR_PU |  (1<<LED_PIN);

      // Init
   TMOD = 0x11;       // set Timers to 16-Bit Mode
   TH0 = 0;           // Reset High-Byte
   TL0 = 0;           // Reset Low-Byte
   TR0 = 1;          
                      // wird jetzt TH0:TL0 um 1 hochgezählt
   ET0 = 1;           // Activate Timer 0 Interrupt
   EA  = 1;           //Activate Globle Interrupt

}
void loop()
{
  //do something with the counter
}
#pragma NOOVERLAY
void Timer0(void) __interrupt (INT_NO_TMR0)
{
        counter = counter + 1;
        LED = !LED;
        TH0 = 0;  // reset of High-Byte
        TL0 = 0;  // reset of Low-Byte
}
DeqingSun commented 3 years ago

If you check wiring.c you will see the timer0 is reserved for millis and micros function for timing. This is a common practice for Arduino. You can use T2, or T1 if you don't use the uart module. If you want to use interrupt. You need to add handler both in your code and main.c.

And using direct register acesss is generally not recommended for Arduino, unless the library can not do what you want.

Vykynger commented 3 years ago

Actually, it seems like I am configuring the Timers wrong because Timer 1 and external Interrupt 1 are not working either. Unfortunately, I did not find any example of a CH55x Timer implementation using the Arduino IDE. Do you know where to find a working example? Also, I did not quite understand the #pragma NOOVERLAY thing because the Arduino IDE does not seem to recognise it.

Vykynger commented 3 years ago

But thanks a lot for the hint with Timer 0. I would have never thought about that. :)

Vykynger commented 3 years ago

Regarding If you want to use interrupt. You need to add handler both in your code and main.c. : I finally found the main.c file in /home/username/.arduino15/packages/CH55xDuino/hardware/mcs51/0.0.9/cores/ch55xduino So thanks a lot! :) Now I only have to find out, how to setup the ext. Interrupt 1. In the main.c file there are both external interrupts already occupied with void INT1_ISR(void) __interrupt (INT_NO_INT1) { intFunc[1](); } So how do I add my own External interrupt? Regarding And using direct register access is generally not recommended for Arduino unless the library can not do what you want : How can I configure the timers then? Do you mean for example using: IE = 0; IE |= (1<<EA); instead of EA = 1? I am not that proficient in C.

DeqingSun commented 3 years ago

Those existing isr handlers are for External int 0 and 1, and timer 0

Vykynger commented 3 years ago

Ok thanks for that fast answer. But how do I set up an external Interrupt then? What ist intFunc[1]? Again writing an normal ISR that handles te external interrupt in the Arduino file does not seem to work. Also naming the ISR in the Arduino Code INT1_ISR(void) does not work either. Can you maybe just give me an example or tell me a little bit detailed on how to use the Ext. Interrupt with the Arduino IDE? Below this there is an example that I would like to get to run using the Arduino IDE.:

#include <ch554.h>
#include <debug.h>

#define LED_PIN 7
SBIT(LED, 0x90, LED_PIN);
void main() {
    CfgFsys();
    P1_DIR_PU &= 0x0C;
    P1_MOD_OC = P1_MOD_OC & ~(1<<LED_PIN);
    P1_DIR_PU = P1_DIR_PU | (1<<LED_PIN);

      // Initialisierung
   IT1 = 1;    // Falling-Edge Trigger for Ext. Interrupt 1
   EX1 = 1;    // External Inteerupt 1 aktivieren
   EA  = 1;    // Globalen Interrupt aktivieren
   while (1) 
   {
   }
}
void Ext(void) __interrupt (INT_NO_INT1)
{
        LED = !LED;
}
DeqingSun commented 3 years ago

Check https://github.com/Blinkinlabs/ch554_sdcc/blob/3b86045fbefc1ff38484acbfa4289cf923451033/include/ch554.h#L695 for info about adding additional ISR in main.c. That will give you a hint about how to add another ISR.

Back to you external ISR request, check https://github.com/DeqingSun/ch55xduino/blob/ch55xduino/ch55xduino/ch55x/libraries/Generic_Examples/examples/02.Digital/AttachInterrupts/AttachInterrupts.ino

If you have never played with any Arduino board, try the examples to understand how the Arduino works.

Vykynger commented 3 years ago

Thank you very very much for your help! I had not found this example library yet. But with it is really easy to program a wch552 with the Arduino IDE. :)