any time I've ever programmed for the 8051 I've usually always cut and pasted. I have had the luxury of doing anything I've ever needed to using Atmels products via Arduino. The engineer on this project however wants me to learn 8051. I understand that he is trying to help me and that the 8051 is a vastly superior and in the long run a better product for me to learn. I went out and bought "C and the 8051" by Thomas Schultz ans well as the 8051 micro development kit. it would figure the very first startup program and I am already confused. The code can be found below:
//------------------------------------------------------------------------------------
// F02x_Blinky.c
//------------------------------------------------------------------------------------
// Copyright (C) 2007 Silicon Laboratories, Inc.
//
// AUTH: BW
// DATE: 4 SEP 01
//
// This program flashes the green LED on the C8051F020 target board about five times
// a second using the interrupt handler for Timer3.
// Target: C8051F02x
//
// Tool chain: KEIL Eval 'c'
//
//------------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------------
#include <c8051f020.h> // SFR declarations
//------------------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F02x
//------------------------------------------------------------------------------------
sfr16 DP = 0x82; // data pointer
sfr16 TMR3RL = 0x92; // Timer3 reload value
sfr16 TMR3 = 0x94; // Timer3 counter
sfr16 ADC0 = 0xbe; // ADC0 data
sfr16 ADC0GT = 0xc4; // ADC0 greater than window
sfr16 ADC0LT = 0xc6; // ADC0 less than window
sfr16 RCAP2 = 0xca; // Timer2 capture/reload
sfr16 T2 = 0xcc; // Timer2
sfr16 RCAP4 = 0xe4; // Timer4 capture/reload
sfr16 T4 = 0xf4; // Timer4
sfr16 DAC0 = 0xd2; // DAC0 data
sfr16 DAC1 = 0xd5; // DAC1 data
//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------
#define SYSCLK 2000000 // approximate SYSCLK frequency in Hz
sbit LED = P1^6; // green LED: '1' = ON; '0' = OFF
//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------
void PORT_Init (void);
void Timer3_Init (int counts);
void Timer3_ISR (void);
//------------------------------------------------------------------------------------
// MAIN Routine
//------------------------------------------------------------------------------------
void main (void) {
// disable watchdog timer
WDTCN = 0xde;
WDTCN = 0xad;
PORT_Init ();
Timer3_Init (SYSCLK / 12 / 10); // Init Timer3 to generate interrupts
// at a 10Hz rate.
EA = 1; // enable global interrupts
while (1) { // spin forever
}
}
//------------------------------------------------------------------------------------
// PORT_Init
//------------------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports
//
void PORT_Init (void)
{
XBR2 = 0x40; // Enable crossbar and weak pull-ups
P1MDOUT |= 0x40; // enable P1.6 (LED) as push-pull output
}
//------------------------------------------------------------------------------------
// Timer3_Init
//------------------------------------------------------------------------------------
//
// Configure Timer3 to auto-reload and generate an interrupt at interval
// specified by <counts> using SYSCLK/12 as its time base.
//
void Timer3_Init (int counts)
{
TMR3CN = 0x00; // Stop Timer3; Clear TF3;
// use SYSCLK/12 as timebase
TMR3RL = -counts; // Init reload values
TMR3 = 0xffff; // set to reload immediately
EIE2 |= 0x01; // enable Timer3 interrupts
TMR3CN |= 0x04; // start Timer3
}
//------------------------------------------------------------------------------------
// Interrupt Service Routines
//------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------
// Timer3_ISR
//------------------------------------------------------------------------------------
// This routine changes the state of the LED whenever Timer3 overflows.
//
void Timer3_ISR (void) interrupt 10
{
TMR3CN &= ~(0x80); // clear TF3
LED = ~LED; // change state of LED
}
I just copied and pasted the code from example. What I'm concerned about is I don't understand the 10hz timer rate. 2000000 / 12 / 10 is roughly 1.67khz I tried dividing later on by 8Mhz (what I believe to be the internal crystal frequency) and no mater if I use (PEMDAS vs BODMAS shouldn't matter) I do not get my 10Hz. Would anyone mind telling me what is going on? I've tried to even factor in Instructions per second and still cannot arrive at 10.
My second question is how does the Timer3_ISR interrupt excecute? I understand when the counting gets to about 17k that it resets but how does it know to go to that function? what if I wanted this function to execute every %100 == 0 or something to that effect? I don't see anything comparing or 'tripping' this to go.
I apologize for my ignorance, I've done some pretty neat projects with easy things like the arduino and copied and pasted 8051 but it's like I have to start ALL over again. I know it is for the better however. Thanks
//------------------------------------------------------------------------------------
// F02x_Blinky.c
//------------------------------------------------------------------------------------
// Copyright (C) 2007 Silicon Laboratories, Inc.
//
// AUTH: BW
// DATE: 4 SEP 01
//
// This program flashes the green LED on the C8051F020 target board about five times
// a second using the interrupt handler for Timer3.
// Target: C8051F02x
//
// Tool chain: KEIL Eval 'c'
//
//------------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------------
#include <c8051f020.h> // SFR declarations
//------------------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F02x
//------------------------------------------------------------------------------------
sfr16 DP = 0x82; // data pointer
sfr16 TMR3RL = 0x92; // Timer3 reload value
sfr16 TMR3 = 0x94; // Timer3 counter
sfr16 ADC0 = 0xbe; // ADC0 data
sfr16 ADC0GT = 0xc4; // ADC0 greater than window
sfr16 ADC0LT = 0xc6; // ADC0 less than window
sfr16 RCAP2 = 0xca; // Timer2 capture/reload
sfr16 T2 = 0xcc; // Timer2
sfr16 RCAP4 = 0xe4; // Timer4 capture/reload
sfr16 T4 = 0xf4; // Timer4
sfr16 DAC0 = 0xd2; // DAC0 data
sfr16 DAC1 = 0xd5; // DAC1 data
//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------
#define SYSCLK 2000000 // approximate SYSCLK frequency in Hz
sbit LED = P1^6; // green LED: '1' = ON; '0' = OFF
//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------
void PORT_Init (void);
void Timer3_Init (int counts);
void Timer3_ISR (void);
//------------------------------------------------------------------------------------
// MAIN Routine
//------------------------------------------------------------------------------------
void main (void) {
// disable watchdog timer
WDTCN = 0xde;
WDTCN = 0xad;
PORT_Init ();
Timer3_Init (SYSCLK / 12 / 10); // Init Timer3 to generate interrupts
// at a 10Hz rate.
EA = 1; // enable global interrupts
while (1) { // spin forever
}
}
//------------------------------------------------------------------------------------
// PORT_Init
//------------------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports
//
void PORT_Init (void)
{
XBR2 = 0x40; // Enable crossbar and weak pull-ups
P1MDOUT |= 0x40; // enable P1.6 (LED) as push-pull output
}
//------------------------------------------------------------------------------------
// Timer3_Init
//------------------------------------------------------------------------------------
//
// Configure Timer3 to auto-reload and generate an interrupt at interval
// specified by <counts> using SYSCLK/12 as its time base.
//
void Timer3_Init (int counts)
{
TMR3CN = 0x00; // Stop Timer3; Clear TF3;
// use SYSCLK/12 as timebase
TMR3RL = -counts; // Init reload values
TMR3 = 0xffff; // set to reload immediately
EIE2 |= 0x01; // enable Timer3 interrupts
TMR3CN |= 0x04; // start Timer3
}
//------------------------------------------------------------------------------------
// Interrupt Service Routines
//------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------
// Timer3_ISR
//------------------------------------------------------------------------------------
// This routine changes the state of the LED whenever Timer3 overflows.
//
void Timer3_ISR (void) interrupt 10
{
TMR3CN &= ~(0x80); // clear TF3
LED = ~LED; // change state of LED
}
I just copied and pasted the code from example. What I'm concerned about is I don't understand the 10hz timer rate. 2000000 / 12 / 10 is roughly 1.67khz I tried dividing later on by 8Mhz (what I believe to be the internal crystal frequency) and no mater if I use (PEMDAS vs BODMAS shouldn't matter) I do not get my 10Hz. Would anyone mind telling me what is going on? I've tried to even factor in Instructions per second and still cannot arrive at 10.
My second question is how does the Timer3_ISR interrupt excecute? I understand when the counting gets to about 17k that it resets but how does it know to go to that function? what if I wanted this function to execute every %100 == 0 or something to that effect? I don't see anything comparing or 'tripping' this to go.
I apologize for my ignorance, I've done some pretty neat projects with easy things like the arduino and copied and pasted 8051 but it's like I have to start ALL over again. I know it is for the better however. Thanks