IMDL: I am sorry for not being able to talk on Thursday, I have class until about 2:15 and I had a job interview at 2:45. Anyway. So I am going to try to explain some basics for programming. If I make a mistake, email me and let me know. If I am not clear about something, email me. So, like I mentioned in the last email, you need to get driver code working. These routines will allow you to control all of your actuators and read in data from your sensors. I will explain how to write initialization routines for the major systems on the HC11, how you can use them, and any other details. So, here we go. I. Important HC11 systems Just so all of you know, I will explain some of the systems of the HC11 and how you can use them to program your robot. I may make errors; its been a while since I've been in 4744. One note: I want to make sure that everyone remembers what happens when you use interrupts in 4744; you basically go execute an ISR. It is the same thing when you program the HC11 in C, when an interrupt is requested and everything is set up properly, an interrupt service function is run. A. SCI System: Most of you know what this is, an asynchronous serial port. So you can use it to interface to any RS232 devices. If you are going to use it to interface to a device, remember that you have to also use it to download code to the HC11. You can send and receive data from this port by writing and reading to the SCDR register (more later). B. SPI: A synchronous serial port, send and receive serial data using a clock. Similar to above, but uses the SPDR. C. Real Time Interrupt: This is an interrupt that can be set to occur at a periodic rate. D. OC: Generate PWM for controlling motors and servos E. IC: read PWM signals F. TOF: similar to RTI, a periodic interrupt G. PA: Pulse Accumulator, for reading in a number of pulses, it is asynchronous. H. A to D: Reads in an analog voltage OK, to initialize the SCI port. void init_sci(void){ //Set baud rate to 9600 (SCP1 = 1, SCP0 = 1, SCR2 = SCR1 = SCR0 = 0) CLEAR_BIT(BAUD, 0x07); SET_BIT(BAUD, 0x30); //Set control registers CLEAR_BIT(SCCR1, 0xFF); //Set SCCR2 for Transmit Enable, Receive Enable, and Receive Interrupt Enable (so SCI_isr is called when data is sent to the SCI system) SET_BIT(SCCR2, 0x2C); }//End init_sci Here is what you need to do to send data: SCDR = data; Remember, the SCI system sends out any data that is sent to the SCI data register (SCDR). To receive data , you use the SCI_isr routine void SCI_isr(void){ //Read the SCSR, then SCDR just to clear the flag temp = SCSR; //Grab the data data = SCDR; //Do whatever you want to with the data }//End SCI_isr OK, I haven't messed with SPI too much so I am not going to write any code for it. If you REALLY need it and can't figure it out, email me. To initialize the RTI. void init_rti(void){ //Turn off interrupts INTR_OFF(); //Set RTI rate CLEAR_BIT(PACTL, 0x03); //Enable RTI Interrupt SET_BIT(TMSK2, 0x40); //Turn on interrupts INTR_ON(); }//End init_rti Ok, once RTI is initialized, you WILL EXECUTE the RTI_isr function EVERY TIME the interrupt is requested, ie, if the timer bits were set to interrupt every 32 ms, you will execute this function every 32 ms. void RTI_isr(void){ //Clear the flag CLEAR_FLAG(TFLG2, 0x40); //Do whatever you want to in this routine }//End RTI_isr Output compare.. I guess everyone needs this part. You will need to use OC to generate PWM signals to control your motors and servos. Here is an initialization: void init_toc(void){ //Turn off interrupts INTR_OFF(); //TOC2 initialization SET_BIT(TCTL1, 0x80); //Enable OC2 for falling edge on first successful compare (safe default) CLEAR_BIT(TCTL1, 0x40); SET_BIT(TMSK1, 0x40); //Enable OC2 mask //TOC3 init SET_BIT(TCTL1, 0x40); CLEAR_BIT(TCTL1, 0x20); SET_BIT(TMSK1, 0x20); }//End init_toc You do similar things for the other OCs. As for the interrupt service routines. void TOC2_isr(void){ int temp = 0; //Clear the flag CLEAR_FLAG(TFLG1, 0x40); //Set the number of eclock for the duty cycle temp = (duty2 / 100.0) * PERIOD; //If the number if eclocks is < 500, not enough time for entire ISR, so set pin LOW if(temp < 500){ CLEAR_BIT(TCTL1, 0x40); SET_BIT(CFORC, 0x40); } //If PERIOD - eclocks < 500, not enough time for full ISR, set pin HIGH else if(temp > (PERIOD - 500)){ SET_BIT(TCTL1, 0x40); SET_BIT(CFORC, 0x40); } //Otherwise, check current state and add proper amount to TOC2 register else if(TCTL1 & 0x40){ //If you are here, you are HIGH, set to got LOW NEXT, add duty eclock count CLEAR_BIT(TCTL1, 0x40); TOC2 += temp; } else { //If you are here you are LOW, set to go HIGH, add PERIOD - duty SET_BIT(TCTL1, 0x40); TOC2 += (PERIOD - temp); } } To initialize the A to D system: (this may be wrong, I haven't used this in a while) void init_atod(void){ //Turn on A to D SET_BIT(OPTION, 0x80); //Wait a bit for AD to stabilize wait(); //Set for SCAN CLEAR_BIT(ADCTL, 0xFF); SET_BIT(ADCTL, 0x20); }//End init_atod To read from the AD port.. I still need to go over this, I forgot what the SCAN and MULT bits do. I hope this was helpful. Email me if you have any more questions. ************************************************* Scott Nortman Teaching Assistant Machine Intelligence Lab University of Florida (352) 846-3993 *************************************************