I am going to do a project with 8052,DS89C450 and RTC CDP68HC68T1 which is communication with SPI. and i am going to program LCD can show the calendar and time and even from keypad we can change time and date. however i am really a freshman with this device at all especially the programming about SPI. can anybody help me?
The way to go is to get all the documents available for your processor and the peripherial chips. Then look for all application notes and source code.
After having spent time going through this available material (which does take time but have to take time since we can't be lucky enough to learn with no time spent), you would either know enough to write own code or modify sample code. Or you would have managed to get stuck on a number of very specific questions - questions well suited to ask for clarification about on this or other forums.
In short - we can't really help much until you have got your hands dirty by fighting enough that you know where you are stuck.
Note that even sample code for other processors are meaningful to look at, when trying to learn the required basic concepts involved. If the processor requires that you do the SPI manually, then it's just a question of what register names and bits that controls the specific I/O pins. If using a processor with hardware SPI (which is very common since SPI is simple to implement in silicon) then most chips have very similar design so knowing SPI for one processor makes it very easy to read sample SPI code for another processor and understand exactly what is done and why.
8052,DS89C450 and RTC CDP68HC68T1 you describe fully your peripheral chips and then just say "8052" I hope it is not a 8052, give manufacturer and FULL name of the chip
Erik
now i am programming some, but the problem is that the time shown on LCD cannot run by itself and the shown time is not match what i set in initial clock time in programming. i dun know why it happen and hw it happen can i send you my program to have a check?
program: #include<DS89C4xx.h> #include<stdio.h> #include<intrins.h> //keil library (is used for _nop_()_operation) #include<string.h> //strlen()function #include<absacc.h> //XBYTE function
#define BYTE unsigned char #define SECONDS 0x20 #define MINUTES 0x21 #define HOURS 0x22 #define DAYOFWEEK 0x23 #define DATE 0x24 #define MONTH 0x25 #define YEARS 0x26 #define SEC_ALARM 0x28 //set second to alarm #define MIN_ALARM 0x29 //set minute to alarm #define HRS_ALARM 0x2A //set hour to alarm #define STATUS_REG 0x30 //status register #define CONTROL_REG 0x31 //control register #define INTERRUPT 0x32 //interrupt Control Register
sbit SCK = P1^7; //Serial Clock sbit MOSI = P3^4; //master output, slave input sbit MISO = P3^5; //master input, slave output sbit CS2 = P1^1; //chip enable high RTC
#define PortA 0x4000 #define PortB 0x4001 #define PortC 0x4002 #define Control_Register 0x4003
#define TurnOn 0x0C //set the display #define setfunction 0x38 //8-bit bus & 2 line display and 5x8 dots format display mode #define clr 0x01 //clear all the display data #define reHome 0x02 //return cursor to original site and return display to original status #define Inc 0x06 #define IncMode 0x07 #define goline2 0xC0
//===============================================================================// //*SPI Operation for Active Power*// //===============================================================================//
unsigned long Read_Data; void s_delay(int num); void Init_SPI(void); void SPI_Out(BYTE b); BYTE SPI_In(void); void Write_SPI(BYTE b); void Read_SPI (BYTE b); void Delay(int count); void Init_Uart(); void Uart_Tx1(BYTE c); void LCD_WriteInstructionReg(unsigned char Instruction); void LCD_WriteDataReg(unsigned char Value); void InitialiseLCD(void); void InitialiseLCD2(void); void LCD_DisplayString(char*String); BYTE tc,hh; void Init_Clock(void);
void main(void) { BYTE sec, min, hrs; BYTE xdata s[50]; int i; PMR = PMR | 0x81; Delay(100); Init_Uart(); Init_Clock(); //Edge Trigger while(1) { CS2 = 1; SPI_Out(SECONDS); sec = SPI_In(); min = SPI_In(); hrs = SPI_In();
InitialiseLCD2(); sprintf(s, "Time:%02x:%02x:%02x \0", (int)hrs, (int)min, (int)sec); LCD_DisplayString(s); for(i=0; i<strlen(s); i++) Uart_Tx1(s[i]); CS2 = 0; Delay(750); } }
void s_delay(int num) { int i; for(i=0; i<num; i++) _nop_(); } /*The master sets a bit on the MOSI and then generates a clock pulse, after which the next bit is set and another clock pulse is generated, etc. A clock pulse is generated by simply setting the SCK bit high and then low again after a few microseconds. */ void SPI_Out(BYTE b) { int i; SCK = 0; for(i=7; i>0; i--) { if(b&(1<<i)) MOSI = 1; else MOSI = 0; _nop_(); _nop_(); SCK = 1; _nop_(); _nop_(); _nop_(); SCK = 0; _nop_(); _nop_(); } }
BYTE SPI_In(void) { int i; BYTE b = 0; SCK = 0; for(i=7; i>=0; i--) { SCK = 1; _nop_(); _nop_(); if(MISO) b |= 1<<i; _nop_(); _nop_(); _nop_(); SCK = 0; _nop_(); _nop_(); } return(b); }
//=============================================================================================== /*Serial Port Initialization*/
void Delay(int count) { int i, j; for(i=0; i<count; i++) { for(j=0; j<1200; j++); } }
void Init_Uart() //------------------------------------------------------------------------------------------------ //19200 bps @11.059MHz { PCON |= 0x80; //Set SMOD SCON1 = 0x50; //8-bit,rx enable TL1 = 0x00; //Lower Byte TH1 = 0xFD; //Upper Byte TR1 = 1; //Run timer //Baud Rate: 19200 bps }
void Uart_Tx1(BYTE c) { while(TI_1==0); TI_1 = 0; SBUF1 = c; } //---------------------------------------------------------------------------------
void LCD_WriteInstructionReg(unsigned char Instruction) { XBYTE[PortB] = 0x00; XBYTE[PortB] = 0x04; Delay(20); XBYTE[PortA] = Instruction; XBYTE[PortB] = 0x00; }
void LCD_WriteDataReg(unsigned char Value) { XBYTE[PortB] = 0x01; XBYTE[PortB] = 0x05; Delay(20); XBYTE[PortA] = Value; XBYTE[PortB] = 0x00; }
void InitialiseLCD(void) { XBYTE[Control_Register] = 0x81; LCD_WriteInstructionReg(TurnOn); //TurnOn display, No Blink LCD_WriteInstructionReg(setfunction); //8bits bus mode, 2line display, 5x8dots format LCD_WriteInstructionReg(clr); LCD_WriteInstructionReg(IncMode); //Incmode LCD_WriteInstructionReg(Inc); //Inc LCD_WriteInstructionReg(reHome); //return home }
void InitialiseLCD2(void) { XBYTE[Control_Register] = 0x81; LCD_WriteInstructionReg(TurnOn); //turn on display, no blink LCD_WriteInstructionReg(setfunction); //8bits bus mode, 2line display, 5x8dots format LCD_WriteInstructionReg(IncMode); //IncMode LCD_WriteInstructionReg(Inc); //Inc LCD_WriteInstructionReg(reHome); //return home }
void LCD_DisplayString(char*String) { int k=0; while(String[k]) { LCD_WriteDataReg(String[k++]); } }
//===========================================================================================================
void Init_Clock(void) { CS2 = 1; SPI_Out(SECONDS); SPI_Out(0x30); CS2 = 0; _nop_(); _nop_();
CS2 = 1; SPI_Out(MINUTES); SPI_Out(0x10); CS2 = 0; _nop_(); _nop_();
CS2 = 1; SPI_Out(HOURS); SPI_Out(0x01); CS2 = 0; _nop_(); _nop_();
CS2 = 1; SPI_Out(CONTROL_REG); SPI_Out(0x85); CS2 = 0; _nop_(); _nop_();
}
No, apparently you can't - not in a legible fashion, anyhow!
There are clearly stated instructions for how to post source code:
www.danlhenry.com/.../keil_code.png
IF you can miss something as clear as that, it is likely that you have missed similar stuff in writing your code - so you should probably start by going back a carefully studying the documentation for the components you are using...
Note that you will not get anyone to really care about your source code as long as you don't post readable code. Notice the difference between the "code" in your post, and what it looks like in my post?
void main(void) { BYTE sec, min, hrs; BYTE xdata s[50]; int i; PMR = PMR | 0x81; Delay(100); <=== what time unit is this? is your delay even correctly implemented? Init_Uart(); Init_Clock(); //Edge Trigger while(1) { CS2 = 1; SPI_Out(SECONDS); <=== shouldn't you have a comment what this line does? sec = SPI_In(); min = SPI_In(); hrs = SPI_In(); InitialiseLCD2(); <=== initialize every iteration of the loop? why? sprintf(s, "Time:%02x:%02x:%02x \0", (int)hrs, (int)min, (int)sec); LCD_DisplayString(s); for(i=0; i<strlen(s); i++) Uart_Tx1(s[i]); CS2 = 0; Delay(750); } }
Now the problem is I dun know how to use keypad to change time shown on RTC, and the alarm is not working. I would like to show something after 1 min on LCD, but whatever i try got nothing shown out.
#include<DS89C4xx.h> #include<stdio.h> #include<intrins.h> //keil library (is used for _nop_()_operation) #include<string.h> //strlen()function #include<absacc.h> //XBYTE function #define BYTE unsigned char #define SECONDS 0x20 #define MINUTES 0x21 #define HOURS 0x22 #define DAYOFWEEK 0x23 #define DATE 0x24 #define MONTH 0x25 #define YEARS 0x26 #define SEC_ALARM 0x28 //set second to alarm #define MIN_ALARM 0x29 //set minute to alarm #define HRS_ALARM 0x2A //set hour to alarm #define STATUS_REG 0x30 //status register #define CONTROL_REG 0x31 //control register #define INTERRUPT 0x32 //interrupt Control Register sbit SCK = P1^7; //Serial Clock sbit MOSI = P3^4; //master output, slave input sbit MISO = P3^5; //master input, slave output sbit CS2 = P1^1; //chip enable high RTC #define PortA 0x4000 #define PortB 0x4001 #define PortC 0x4002 #define Control_Register 0x4003 #define TurnOn 0x0C //set the display #define setfunction 0x38 //8-bit bus & 2 line display and 5x8 dots format display mode #define clr 0x01 //clear all the display data #define reHome 0x02 //return cursor to original site and return display to original status #define Inc 0x06 #define IncMode 0x07 #define goline2 0xC0 unsigned char xdata s[20]; BYTE sec, min, hrs; BYTE tc; BYTE hh; void SPI_Out(BYTE b); BYTE SPI_In(void); void Write_SPI(BYTE b); void Read_SPI (BYTE b); void Delay(int count); void Init_Uart(); void Uart_Tx1(BYTE c); void LCD_WriteInstructionReg(unsigned char Instruction); void LCD_WriteDataReg(unsigned char Value); void InitialiseLCD(void); void InitialiseLCD2(void); void LCD_DisplayString(char*String); void Init_Clock(void); void Alarm_Clock(void); void ext_int0(void); unsigned char trans_keypad(void); unsigned char keypad (void); void main(void) { BYTE xdata s[20]; int i; PMR = PMR | 0x81; //Perpendicular Magnetic Recording Delay(100); Init_Uart(); Init_Clock(); EA = 1; //Enable Ext interrupt0 EX0 = 1; IT0 = 1; //Edge Trigger Alarm_Clock(); //intitialise RTC to interrupt every 60sec LCD_WriteInstructionReg(clr); while(1) { CS2 = 1; SPI_Out(SECONDS); sec = SPI_In(); min = SPI_In(); hrs = SPI_In(); InitialiseLCD2(); sprintf(s, "%02x:%02x:%02x \0", (int)hrs, (int)min, (int)sec); //show time on LCD LCD_DisplayString(s); for(i=0; i<strlen(s); i++) Uart_Tx1(s[i]); CS2 = 0; Delay(750); } } void SPI_Out(BYTE b) { int i; SCK = 0; for(i=7; i>=0; i--) { if(b&(1<<i)) MOSI = 1; else MOSI = 0; _nop_(); _nop_(); SCK = 1; _nop_(); _nop_(); _nop_(); SCK = 0; _nop_(); _nop_(); } } BYTE SPI_In(void) { int i; BYTE b = 0; SCK = 0; for(i=7; i>=0; i--) { SCK = 1; _nop_(); _nop_(); if(MISO) b |= 1<<i; _nop_(); _nop_(); _nop_(); SCK = 0; _nop_(); _nop_(); } return(b); } void Write_SPI(BYTE b) { BYTE value = 0; value = b | 0x80; //Write operation SPI_Out(value); } void Read_SPI(BYTE b) { BYTE value = 0; value = b | 0x00; //read operation SPI_Out(value); } /*Serial Port Initialization*/ void Delay(int count) { int i, j; for(i=0; i<count; i++) { for(j=0; j<1200; j++); } }
void Init_Uart() //19200 bps { SCON0 = 0x52; PCON |= 0X80;//set baud rate 19200 SCON1 = 0x52; PCON |= 0X80;//set SMOD =1 to get larger baud rate TMOD = 0X21; TH1 = 0XFD; //Baud Rate: 19200 bps TR1 = 1; }
void Uart_Tx1(BYTE c) // transmit data { while(TI_1==0); TI_1 = 0; SBUF1 = c; } void LCD_WriteInstructionReg(unsigned char Instruction) { XBYTE[PortB] = 0x00; XBYTE[PortB] = 0x04; Delay(20); XBYTE[PortA] = Instruction; XBYTE[PortB] = 0x00; } void LCD_WriteDataReg(unsigned char Value) { XBYTE[PortB] = 0x01; XBYTE[PortB] = 0x05; Delay(20); XBYTE[PortA] = Value; XBYTE[PortB] = 0x00; }
void LCD_DisplayString(char*String) { int k=0; while(String[k]) { LCD_WriteDataReg(String[k++]); } } void Init_Clock(void) { BYTE keys,keym,keyh; keys=trans_keypad(); keym=trans_keypad(); keyh=trans_keypad(); CS2 = 1; //initialize time for testing : 03:40:00 Write_SPI(SECONDS); SPI_Out(keys); CS2 = 0; _nop_(); _nop_(); CS2 = 1; Write_SPI(MINUTES); SPI_Out(keym); CS2 = 0; _nop_(); _nop_(); CS2 = 1; Write_SPI(HOURS); SPI_Out(keyh); CS2 = 0; _nop_(); _nop_(); CS2 = 1; Write_SPI(CONTROL_REG); SPI_Out(0x85); CS2 = 0; _nop_(); _nop_(); }
void Alarm_Clock(void) { tc = 0x01; hh = 0x00; CS2 = 1; //set alarm to 00:00:60 Write_SPI(SEC_ALARM); SPI_Out(0x00); CS2 = 0; _nop_(); _nop_(); CS2 = 1; //set alarm to 00:00:60 Write_SPI(MIN_ALARM); SPI_Out(tc); CS2 = 0; _nop_(); _nop_(); CS2 = 1; //set alarm to 00:00:60 Write_SPI(HRS_ALARM); SPI_Out(hh); CS2 = 0; _nop_(); _nop_(); CS2 = 1; Write_SPI(INTERRUPT); //set alarm SPI_Out(0x10); CS2 = 0; _nop_(); _nop_(); } void SMS(void) { int i; LCD_WriteInstructionReg(reHome); CS2=1; SPI_Out(SECONDS); sec=SPI_In(); min=SPI_In(); hrs=SPI_In(); LCD_WriteInstructionReg(goline2);
sprintf (s,"%02x:%02x:%02x \0", (int)hrs, (int)min, (int)sec); LCD_DisplayString(s); for (i=0;i<strlen(s);i++) Uart_Tx1(s[i]); CS2=0; Delay(500); } unsigned char keypad(void) { int val0,val1,val2,val3; XBYTE[PortC]=0x80; Delay(1); val0=XBYTE[PortC]; if(val0 != 0x80) { switch(val0) { case 0x88 : return('1'); //key 1 case 0x84 : return('4'); //key 4 case 0x82 : return('7'); //key 7 case 0x81 : return('*'); //key * } } XBYTE[PortC]=0x40; Delay(1); val1=XBYTE[PortC]; if(val1 != 0x40) { switch(val1) { case 0x48 : return('2'); //key 2 case 0x44 : return('5'); //key 5 case 0x42 : return('8'); //key 8 case 0x41 : return('0'); //key 0 } } XBYTE[PortC]=0x20; Delay(1); val2=XBYTE[PortC]; if(val2 != 0x20) { switch(val2) { case 0x28 : return('3'); //key 3 case 0x24 : return('6'); //key 6 case 0x22 : return('9'); //key 9 case 0x21 : return('#'); //key # } } XBYTE[PortC]=0x10; Delay(1); val3=XBYTE[PortC]; if(val3 != 0x10) { switch(val3) { case 0x18 : return('A'); //key A case 0x14 : return('B'); //key B case 0x12 : return('C'); //key C case 0x11 : return('D'); //key D } } return(0); } unsigned char trans_keypad(void) { BYTE key; while(1) { key=keypad(); //wait until the kay be pressed while(keypad()!=0); //wait tilldepress if (key!=0) Uart_Tx1(key); //transmit key to COM2 Delay(100); } return (key); }
void ext_int0(void) interrupt 0 { int i; int idata mini; mini=0; mini++; while(mini==2) { SMS(); mini=0; } //the following reset interrupt of RTC CS2 = 1; //Read Status Reg to activate interrupt 1 (set alarm interrupt) Read_SPI(STATUS_REG); SPI_Out(0x0A); CS2 = 0; _nop_(); _nop_(); } //------------------------------------------------------------------------------------------------ .
void Init_Uart() //19200 bps { SCON0 = 0x52; PCON |= 0X80;//set baud rate 19200 SCON1 = 0x52; PCON |= 0X80;//set SMOD =1 to get larger baud rate TMOD = 0X21; TH1 = 0XFD; //Baud Rate: 19200 bps TR1 = 1; } void Uart_Tx1(BYTE c) // transmit data { while(TI_1==0); TI_1 = 0; SBUF1 = c; } void LCD_WriteInstructionReg(unsigned char Instruction) { XBYTE[PortB] = 0x00; XBYTE[PortB] = 0x04; Delay(20); XBYTE[PortA] = Instruction; XBYTE[PortB] = 0x00; } void LCD_WriteDataReg(unsigned char Value) { XBYTE[PortB] = 0x01; XBYTE[PortB] = 0x05; Delay(20); XBYTE[PortA] = Value; XBYTE[PortB] = 0x00; } void InitialiseLCD2(void) { XBYTE[Control_Register] = 0x81; LCD_WriteInstructionReg(TurnOn); //turn on display, no blink LCD_WriteInstructionReg(setfunction); //8bits bus mode, 2line display, 5x8dots format LCD_WriteInstructionReg(IncMode); //IncMode LCD_WriteInstructionReg(Inc); //Inc LCD_WriteInstructionReg(reHome); //return home } void LCD_DisplayString(char*String) { int k=0; while(String[k]) { LCD_WriteDataReg(String[k++]); } } void Init_Clock(void) { BYTE keys,keym,keyh; keys=trans_keypad(); keym=trans_keypad(); keyh=trans_keypad(); CS2 = 1; //initialize time for testing : 03:40:00 Write_SPI(SECONDS); SPI_Out(keys); CS2 = 0; _nop_(); _nop_(); CS2 = 1; Write_SPI(MINUTES); SPI_Out(keym); CS2 = 0; _nop_(); _nop_(); CS2 = 1; Write_SPI(HOURS); SPI_Out(keyh); CS2 = 0; _nop_(); _nop_(); CS2 = 1; Write_SPI(CONTROL_REG); SPI_Out(0x85); CS2 = 0; _nop_(); _nop_(); } void Alarm_Clock(void) { tc = 0x01; hh = 0x00; CS2 = 1; //set alarm to 00:00:60 Write_SPI(SEC_ALARM); SPI_Out(0x00); CS2 = 0; _nop_(); _nop_(); CS2 = 1; //set alarm to 00:00:60 Write_SPI(MIN_ALARM); SPI_Out(tc); CS2 = 0; _nop_(); _nop_(); CS2 = 1; //set alarm to 00:00:60 Write_SPI(HRS_ALARM); SPI_Out(hh); CS2 = 0; _nop_(); _nop_(); CS2 = 1; Write_SPI(INTERRUPT); //set alarm SPI_Out(0x10); CS2 = 0; _nop_(); _nop_(); } void SMS(void) { int i; LCD_WriteInstructionReg(reHome); CS2=1; SPI_Out(SECONDS); sec=SPI_In(); min=SPI_In(); hrs=SPI_In(); LCD_WriteInstructionReg(goline2); sprintf (s,"%02x:%02x:%02x \0", (int)hrs, (int)min, (int)sec); LCD_DisplayString(s); for (i=0;i<strlen(s);i++) Uart_Tx1(s[i]); CS2=0; Delay(500); } unsigned char keypad(void) { int val0,val1,val2,val3; XBYTE[PortC]=0x80; Delay(1); val0=XBYTE[PortC]; if(val0 != 0x80) { switch(val0) { case 0x88 : return('1'); //key 1 case 0x84 : return('4'); //key 4 case 0x82 : return('7'); //key 7 case 0x81 : return('*'); //key * } } XBYTE[PortC]=0x40; Delay(1); val1=XBYTE[PortC]; if(val1 != 0x40) { switch(val1) { case 0x48 : return('2'); //key 2 case 0x44 : return('5'); //key 5 case 0x42 : return('8'); //key 8 case 0x41 : return('0'); //key 0 } } XBYTE[PortC]=0x20; Delay(1); val2=XBYTE[PortC]; if(val2 != 0x20) { switch(val2) { case 0x28 : return('3'); //key 3 case 0x24 : return('6'); //key 6 case 0x22 : return('9'); //key 9 case 0x21 : return('#'); //key # } } XBYTE[PortC]=0x10; Delay(1); val3=XBYTE[PortC]; if(val3 != 0x10) { switch(val3) { case 0x18 : return('A'); //key A case 0x14 : return('B'); //key B case 0x12 : return('C'); //key C case 0x11 : return('D'); //key D } } return(0); } unsigned char trans_keypad(void) { BYTE key; while(1) { key=keypad(); //wait until the kay be pressed while(keypad()!=0); //wait tilldepress if (key!=0) Uart_Tx1(key); //transmit key to COM2 Delay(100); } return (key); } void ext_int0(void) interrupt 0 { int i; int idata mini; mini=0; mini++; while(mini==2) { SMS(); mini=0; } //the following reset interrupt of RTC CS2 = 1; //Read Status Reg to activate interrupt 1 (set alarm interrupt) Read_SPI(STATUS_REG); SPI_Out(0x0A); CS2 = 0; _nop_(); _nop_(); } //------------------------------------------------------------------------------------------------
.