A. 12864LCD 液晶顯示的流程圖
帶中文字型檔的128X64是一種具有4位/8 位並行、2線或3線串列多種介面方式,內部含有國標一級、二級簡體中文字型檔的點陣圖形液晶顯示模塊。
其顯示解析度為128×64,內置8192個16*16點漢字,和128個16*8點ASCII字元集,利用該模塊靈活的介面方式和簡單、方便的操作指令,可構成全中文人機交互圖形界面。可以顯示8×4行16×16點陣的漢字,也可完成圖形顯示,低電壓低功耗是其又一顯著特點。
由該模塊構成的液晶顯示方案與同類型的圖形點陣液晶顯示模塊相比,不論硬體電路結構或顯示程序都要簡潔得多,且該模塊的價格也略低於相同點陣的圖形液晶模塊。
(1)12864電路程序擴展閱讀:
用帶中文字型檔的128X64顯示模塊時應注意以下幾點:
1.欲在某一個位置顯示中文字元時,應先設定顯示字元位置,即先設定顯示地址,再寫入中文字元編碼。
2.顯示ASCII字元過程與顯示中文字元過程相同。不過在顯示連續字元時,只須設定一次顯示地址,由模塊自動對地址加1指向下一個字元位置,否則,顯示的字元中將會有一個空ASCII字元位置。
3.當字元編碼為2位元組時,應先寫入高位位元組,再寫入低位位元組。
4.模塊在接收指令前,向處理器必須先確認模塊內部處於非忙狀態,即讀取BF標志時BF需為「0」,方可接受新的指令。
如果在送出一個指令前不檢查BF標志,則在前一個指令和這個指令中間必須延遲一段較長的時間,即等待前一個指令確定執行完成。指令執行的時間請參考指令表中的指令執行時間說明。
5.「RE」為基本指令集與擴充指令集的選擇控制位。當變更「RE」後,以後的指令集將維持在最後的狀態,除非再次變更「RE」位,否則使用相同指令集時,無需每次均重設「RE」位。
B. 跪求 51單片機+12864液晶+1302時鍾製成的萬年歷c程序
頂層文件 萬年歷.C
#include<reg51.h>
#include "LCD1602.h"
#include "DS1302.h"
#define uchar unsigned char
#define uint unsigned int
sbit speaker=P2^4;
bit key_flag1=0,key_flag2=0;
SYSTEMTIME adjusted;
uchar sec_add=0,min_add=0,hou_add=0,day_add=0,mon_add=0,yea_add=0;
uchar data_alarm[7]={0};
/************鍵盤控制******************************/
int key_scan() //掃描是否有鍵按下
{ int i=0;
uint temp;
P1=0xf0;
temp=P1;
if(temp!=0xf0)
i=1;
else
i=0;
return i;
}
uchar key_value() //確定按鍵的值
{
uint m=0,n=0,temp;
uchar value;
uchar v[4][3]={'2','1','0','5','4','3','8','7','6','b','a','9'} ;
P1=0xfe; temp=P1; if(temp!=0xfe)m=0;
P1=0xfd;temp=P1 ;if(temp!=0xfd)m=1;
P1=0xfb;temp=P1 ;if(temp!=0xfb)m=2;
P1=0xf7;temp=P1 ;if(temp!=0xf7)m=3;
P1=0xef;temp=P1 ;if(temp!=0xef)n=0;
P1=0xdf;temp=P1 ;if(temp!=0xdf)n=1;
P1=0xbf;temp=P1 ;if(temp!=0xbf)n=2;
value=v[m][n];
return value;
}
/***************************設置鬧鈴函數*******************************/
void naoling(void)
{
uchar i=0,l=0,j;
init1602();
while(key_flag2&&i<12)
if(key_scan()){j=key_value();write_data(j);if(i%2==0)data_alarm[l]=(j-'0')*10;else {data_alarm[l]+=(j-'0');l++;}i++;delay(600);}
write_com(0x01);
}
uchar according(void)
{ uchar k;
if(data_alarm[0]==adjusted.Year&&data_alarm[1]==adjusted.Month&&data_alarm[2]==adjusted.Day&&data_alarm[3]==adjusted.Hour&&data_alarm[4]==adjusted.Minute&&data_alarm[5]==adjusted.Second)
k=1;
else k=0;
return k;
}
void speak(void)
{uint i=50;
while(i)
{speaker=0;
delay(1);
speaker=1;
delay(1);
i--;
}
}
void alarm(void)
{uint i=10;
while(i)
{
speak();
delay(10);
i--;
}
}
/**************************修改時間操作********************************/
void reset(void)
{
sec_add=0;
min_add=0;
hou_add=0;
day_add=0;
mon_add=0;
yea_add=0 ;
}
void adjust(void)
{
if(key_scan()&&key_flag1)
switch(key_value())
{case '0':sec_add++;break;
case '1':min_add++;break;
case '2':hou_add++;break;
case '3':day_add++;break;
case '4':mon_add++;break;
case '5':yea_add++;break;
case 'b':reset();break;
default: break;
}
adjusted.Second+=sec_add;
adjusted.Minute+=min_add;
adjusted.Hour+=hou_add;
adjusted.Day+=day_add;
adjusted.Month+=mon_add;
adjusted.Year+=yea_add;
if(adjusted.Second>59) adjusted.Second=adjusted.Second%60;
if(adjusted.Minute>59) adjusted.Minute=adjusted.Minute%60;
if(adjusted.Hour>23) adjusted.Hour=adjusted.Hour%24;
if(adjusted.Day>31) adjusted.Day=adjusted.Day%31;
if(adjusted.Month>12) adjusted.Month=adjusted.Month%12;
if(adjusted.Year>100) adjusted.Year=adjusted.Year%100;
}
/**************************中斷處理函數*********************************/
void changing(void) interrupt 0 using 0 //需要修改時間和日期,或者停止修改
{
if(key_flag1)key_flag1=0;
else key_flag1=1;
}
void alarming(void) interrupt 3 using 0 //需要設置鬧鈴或者停止設置
{
if(key_flag2)key_flag2=0;
else key_flag2=1;
}
/********************************主函數***********************************/
main()
{uint i;
uchar *l;
uchar p1[]="D:",p2[]="T:";
SYSTEMTIME T;
EA=1;
EX0=1;
IT0=1;
EA=1;
EX1=1;
IT1=1;
init1602();
Initial_DS1302() ;
while(1)
{ write_com(0x80);
write_string(p1,2);
write_com(0xc0);
write_string(p2,2);
DS1302_GetTime(&T) ;
adjusted.Second=T.Second;
adjusted.Minute=T.Minute;
adjusted.Hour=T.Hour;
adjusted.Week=T.Week;
adjusted.Day=T.Day;
adjusted.Month=T.Month;
adjusted.Year=T.Year;
for(i=0;i<9;i++)
{
adjusted.DateString[i]=T.DateString[i];
adjusted.TimeString[i]=T.TimeString[i];
}
adjust();
if(key_flag2)naoling();
if(according())alarm();
DateToStr(&adjusted);
TimeToStr(&adjusted);
write_com(0x82);
write_string(adjusted.DateString,8);
write_com(0xc2);
write_string(adjusted.TimeString,8);
delay(10);
}
(二)頭文件1 顯示模塊 LCD1602.H
#ifndef LCD_CHAR_1602_2009_5_9
#define LCD_CHAR_1602_2009_5_9
#define uchar unsigned char
#define uint unsigned int
sbit lcdrs = P2^0;
sbit lcdrw = P2^1;
sbit lcden = P2^2;
void delay(uint z) // 延時
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void write_com(uchar com) // 寫入指令數據到 lcd
{
lcdrw=0;
lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar date) // 寫入字元顯示數據到 lcd
{
lcdrw=0;
lcdrs=1;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init1602() // 初始化設定
{
lcdrw=0;
lcden=0;
write_com(0x3C);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
}
void write_string(uchar *pp,uint n)
{
int i;
for(i=0;i<n;i++)
write_data(pp[i]);
}
#endif
(三)頭文件2 時鍾模塊 DS1302.H
#ifndef _REAL_TIMER_DS1302_2009_5_20_
#define _REAL_TIMER_DS1302_2003_5_20_
sbit DS1302_CLK = P2^6; //實時時鍾時鍾線引腳
sbit DS1302_IO = P2^7; //實時時鍾數據線引腳
sbit DS1302_RST = P2^5; //實時時鍾復位線引腳
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
typedef struct SYSTEM_TIME
{
unsigned char Second;
unsigned char Minute;
unsigned char Hour;
unsigned char Week;
unsigned char Day;
unsigned char Month;
unsigned char Year;
unsigned char DateString[9]; //用這兩個字元串來放置讀取的時間
unsigned char TimeString[9];
}SYSTEMTIME; //定義的時間類型
#define AM(X) X
#define PM(X) (X+12) // 轉成24小時制
#define DS1302_SECOND 0x80
#define DS1302_MINUTE 0x82
#define DS1302_HOUR 0x84
#define DS1302_WEEK 0x8A
#define DS1302_DAY 0x86
#define DS1302_MONTH 0x88
#define DS1302_YEAR 0x8C
#define DS1302_RAM(X) (0xC0+(X)*2) //用於計算 DS1302_RAM 地址的宏
/******內部指令**********/
void DS1302InputByte(unsigned char d) //實時時鍾寫入一位元組(內部函數)
{
unsigned char i;
ACC = d;
for(i=8; i>0; i--)
{
DS1302_IO = ACC0;
DS1302_CLK = 1;
DS1302_CLK = 0;
ACC = ACC >> 1; //因為在前面已經定義了ACC0 = ACC^0;以便再次利用DS1302_IO = ACC0;
}
}
unsigned char DS1302OutputByte(void) //實時時鍾讀取一位元組(內部函數)
{
unsigned char i;
for(i=8; i>0; i--)
{
ACC = ACC >>1;
ACC7 = DS1302_IO;
DS1302_CLK = 1;
DS1302_CLK = 0;
}
return(ACC);
}
/********************************/
void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要寫的數據
{
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr); // 地址,命令
DS1302InputByte(ucDa); // 寫1Byte數據
DS1302_CLK = 1;
DS1302_RST = 0;
}
unsigned char Read1302(unsigned char ucAddr) //讀取DS1302某地址的數據
{
unsigned char ucData;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(ucAddr|0x01); // 地址,命令
ucData = DS1302OutputByte(); // 讀1Byte數據
DS1302_CLK = 1;
DS1302_RST = 0;
return(ucData);
}
void DS1302_SetProtect(bit flag) //是否防寫
{
if(flag)
Write1302(0x8E,0x10);
else
Write1302(0x8E,0x00);
}
void DS1302_SetTime(unsigned char Address, unsigned char Value) // 設置時間函數
{
DS1302_SetProtect(0);
Write1302(Address, ((Value/10)<<4 | (Value%10))); //將十進制數轉換為BCD碼
} //在DS1302中的與日歷、時鍾相關的寄存器存放的數據必須為BCD碼形式
void DS1302_GetTime(SYSTEMTIME *Time)
{
unsigned char ReadValue;
ReadValue = Read1302(DS1302_SECOND);
Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //將BCD碼轉換為十進制數
ReadValue = Read1302(DS1302_MINUTE);
Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_HOUR);
Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_DAY);
Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_WEEK);
Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_MONTH);
Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
ReadValue = Read1302(DS1302_YEAR);
Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);
}
unsigned char *DataToBCD(SYSTEMTIME *Time)
{
unsigned char D[8];
D[0]=Time->Second/10<<4+Time->Second%10;
D[1]=Time->Minute/10<<4+Time->Minute%10;
D[2]=Time->Hour/10<<4+Time->Hour%10;
D[3]=Time->Day/10<<4+Time->Day%10;
D[4]=Time->Month/10<<4+Time->Month%10;
D[5]=Time->Week/10<<4+Time->Week%10;
D[6]=Time->Year/10<<4+Time->Year%10;
return D;
}
void DateToStr(SYSTEMTIME *Time)
{
//將十進制數轉換為液晶顯示的ASCII值
Time->DateString[0] = Time->Year/10 + '0';
Time->DateString[1] = Time->Year%10 + '0';
Time->DateString[2] = '-';
Time->DateString[3] = Time->Month/10 + '0';
Time->DateString[4] = Time->Month%10 + '0';
Time->DateString[5] = '-';
Time->DateString[6] = Time->Day/10 + '0';
Time->DateString[7] = Time->Day%10 + '0';
Time->DateString[8] = '\0';
}
void TimeToStr(SYSTEMTIME *Time)
{
//將十進制數轉換為液晶顯示的ASCII值
Time->TimeString[0] = Time->Hour/10 + '0';
Time->TimeString[1] = Time->Hour%10 + '0';
Time->TimeString[2] = ':';
Time->TimeString[3] = Time->Minute/10 + '0';
Time->TimeString[4] = Time->Minute%10 + '0';
Time->TimeString[5] = ':';
Time->TimeString[6] = Time->Second/10 + '0';
Time->TimeString[7] = Time->Second%10 + '0';
Time->DateString[8] = '\0';
}
void Initial_DS1302(void)
{
unsigned char Second;
Second=Read1302(DS1302_SECOND);
if(Second&0x80) //初始化時間
DS1302_SetTime(DS1302_SECOND,0);
}
void DS1302_TimeStop(bit flag) // 是否將時鍾停止
{
unsigned char Data;
Data=Read1302(DS1302_SECOND);
DS1302_SetProtect(0);
if(flag)
Write1302(DS1302_SECOND, Data|0x80);
else
Write1302(DS1302_SECOND, Data&0x7F);
}
#endif
C. 誰有用51單片機控制12864顯示數字時鍾的程序!急求!不用ds1302;簡單一點就好。有好的答案加分!
裡面有128564顯示漢字的程序,自己研究下,不過是用msp430控制的,你改改埠i就可以了。
#include "msp430x26x.h"
#define uchar unsigned char
#define uint unsigned int
#define iDat 1 //數據標志
#define iCmd 0 //指令標志
#define LCDb_RS 0x20 //定義四個控制引腳
#define LCDb_RW 0x40
#define LCDb_E 0x80
#define LCDb_RST 0x04
#define LCDb_L1 0x80 //第一行的地址
#define LCDb_L2 0x90 //第二行的地址
#define LCDb_L3 0x88 //第三行的地址
#define LCDb_L4 0x98 //第四行的地址
#define LCDb_SET_RS P1OUT|=LCDb_RS //四個控制管腳的控制操作
#define LCDb_SET_RW P1OUT|=LCDb_RW
#define LCDb_SET_E P1OUT|=LCDb_E
#define LCDb_SET_RST P8OUT|=LCDb_RST
#define LCDb_CLR_RS P1OUT&=~LCDb_RS
#define LCDb_CLR_RW P1OUT&=~LCDb_RW
#define LCDb_CLR_E P1OUT&=~LCDb_E
#define LCDb_CLR_RST P8OUT&=~LCDb_RST
#define LCDb_DO P4OUT //輸出數據匯流排埠定義
#define LCDb_FUNCTION 0x38 // 液晶模式為8位,2行,5*8字元
#define LCDb_BASCMD 0x30 // 基本指令集
#define LCDb_CLS 0x01 // 清屏
#define LCDb_HOME 0x02 // 地址返回原點,不改變DDRAM內容
#define LCDb_ENTRY 0x06 // 設定輸入模式,游標加,屏幕不移動
#define LCDb_C2L 0x10 // 游標左移
#define LCDb_C2R 0x14 // 游標右移
#define LCDb_D2L 0x18 // 屏幕左移
#define LCDb_D2R 0x1C // 屏幕又移
#define LCDb_ON 0x0C // 打開顯示
#define LCDb_OFF 0x08 // 關閉顯示
unsigned char RXData;
unsigned char Seg_Data[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f} ; //數碼管編碼
unsigned char Result[5]; //整數轉化成字元串,給LCD顯示
void Delayms(uint MS)
{
uint i,j;
for( i=0;i<MS;i++)
for(j=0;j<1141;j++);
}
void Delayus(uint US)
{
uint i;
US=US*5/4;
for( i=0;i<US;i++);
}
void LCD12864_portini()
{
P1DIR=0xFF;
P4DIR=0xFF;
P5DIR=0xFF;
P8DIR=0xFF;
P8OUT |=LCDb_RST;
// P1OUT=0xFF;
}
/*函數名稱: LCD12864_sendbyte
功 能: 向12864液晶寫入一個位元組數據或者指令
*/
void LCD12864_sendbyte(uchar DatCmd, uchar dByte)
{
if (DatCmd == iCmd) //指令操作
LCDb_CLR_RS;
else
LCDb_SET_RS;
LCDb_CLR_RW; //寫操作
LCDb_SET_E;
LCDb_DO = dByte; //寫入數據
//Delayus(500);
Delayms(1);
LCDb_CLR_E;
}
/*函數名稱: LCD12864_sendstr
功 能: 向12864液晶寫入一個字元串
參 數: ptString--字元串指針
返回值 : 無
*/
void LCD12864_sendstr(uchar *ptString)
{
while((*ptString)!='\0') //字元串未結束一直寫
{
LCD12864_sendbyte(iDat, *ptString++);
}
}
/*函數名稱: LCD12864_clear
功 能: 12864液晶清屏
參 數: 無
返回值 : 無
*/
void LCD12864_clear(void)
{
LCD12864_sendbyte(iCmd,LCDb_CLS);
Delayms(2);// 清屏指令寫入後,2ms 的延時是很必要的!!!
}
/*
函數名稱: LCD12864_gotoXY
功 能: 移動到指定位置
參 數: Row--指定的行
Col--指定的列
返回值 : 無
*/
void LCD12864_gotoXY(uchar Row, uchar Col)
{
switch (Row) //選擇行
{
case 2:
LCD12864_sendbyte(iCmd, LCDb_L2 + Col); break; //寫入第2行的指定列
case 3:
LCD12864_sendbyte(iCmd, LCDb_L3 + Col); break; //寫入第3行的指定列
case 4:
LCD12864_sendbyte(iCmd, LCDb_L4 + Col); break; //寫入第4行的指定列
default:
LCD12864_sendbyte(iCmd, LCDb_L1 + Col); break; //寫入第1行的指定列
}
}
/*
函數名稱: LCD12864_initial
功 能: 12864液晶初始化
*/
void LCD12864_initial(void)
{
Delayms(100); // 等待內部復位
LCD12864_portini(); //埠初始化
LCD12864_sendbyte(iCmd, LCDb_FUNCTION); //功能、模式設定
LCD12864_sendbyte(iCmd, LCDb_ON); //打開顯示
LCD12864_clear(); //清屏
LCD12864_sendbyte(iCmd, LCDb_ENTRY); // 輸入模式設定
}
void Int_char(int data)
{
if(data/1000)
{
Result[0]=data/1000+'0';
Result[1]=data/100%10+'0';
Result[2]=data/10%10+'0';
Result[3]=data%10+'0';
Result[4]=0;
}
else if(data/100)
{
Result[0]=data/100+'0';
Result[1]=data/10%10+'0';
Result[2]=data%10+'0';
Result[3]=0;
}
else if(data/10)
{
Result[0]=data/10%10+'0';
Result[1]=data%10+'0';
Result[2]=0;
}
else
{
Result[0]=data%10+'0';
Result[1]=0;
}
}
unsigned char Key_Press(void)
{
P7OUT=0xF0;
if((P7IN&0x10)&&(P7IN&0x20)&&(P7IN&0x40)&&(P7IN&0x80)) return 0x00;
else return 0xFF;
}
unsigned char Get_Keycode(void)
{
while(1)
{
P7OUT=0xFE; //掃描第一列
if((P7IN&0x10)==0) return 0;
else if((P7IN&0x20)==0) return 4;
else if((P7IN&0x40)==0) return 8;
else if((P7IN&0x80)==0) return 12;
P7OUT=0xFD; //掃描第二列
if((P7IN&0x10)==0) return 1;
else if((P7IN&0x20)==0) return 5;
else if((P7IN&0x40)==0) return 9;
else if((P7IN&0x80)==0) return 13;
P7OUT=0xFB; //掃描第三列
if((P7IN&0x10)==0) return 2;
else if((P7IN&0x20)==0) return 6;
else if((P7IN&0x40)==0) return 10;
else if((P7IN&0x80)==0) return 14;
P7OUT=0xF7; //掃描第四列
if((P7IN&0x10)==0) return 3;
else if((P7IN&0x20)==0) return 7;
else if((P7IN&0x40)==0) return 11;
else if((P7IN&0x80)==0) return 15;
}
}
void Init_compa()
{
CACTL1 = CAON+CAREF_2+CARSEL; // Enable Comp, ref = 0.5*Vcc = Vin-
CACTL2 = P2CA0; // Pin to CA0
P1DIR |= 0x01; // P1.0 = o/p direction(CAOUT - LED)
P1SEL |= 0x01; // P1.0 - CAOUT, option select
}
/*
** 函數名稱:初始化函數
*/
void Init_IIC(void)
{
P3SEL |= 0x06; // Assign I2C pins to USCI_B0
UCB0CTL1 |= UCSWRST; // Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0;
UCB0I2CSA = 0x50; // Slave Address is 048h
UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
IE2 |= UCB0RXIE; // Enable RX interrupt
_BIS_SR(GIE);
// RXCompare = 0x0; // Used to check incoming data
}
/** 函數名稱:位元組寫函數
*/
void EEPROM_Write(unsigned char high_Address,unsigned char low_Address,unsigned char Word)
{
while (UCB0CTL1 & UCTXSTP); // 確定匯流排空閑
UCB0CTL1 |= UCTXSTT + UCTR; // 發送起始位,確定為發送模式
UCB0TXBUF = high_Address; // 發送高位地址
while((IFG2 & UCB0TXIFG)==0); // 判斷是否發送完畢
UCB0TXBUF = low_Address; // 發送低位地址
while((IFG2 & UCB0TXIFG)==0); // 判斷是否發送完畢
UCB0TXBUF = Word; // 發送數據
while((IFG2 & UCB0TXIFG)==0); // 判斷是否發送完畢
UCB0CTL1 |= UCTXSTP; // 發送停止位
while((UCB0CTL1 & UCTXSTP)==1); // 判斷停止位是否發送完畢
}
/**
** 函數名稱:位元組讀函數
*/
void EEPROM_readmore()
{
UCB0CTL1 &= ~UCTR; // 確定為讀
while (UCB0CTL1 & UCTXSTP); // 匯流排是否空閑
UCB0CTL1 |= UCTXSTT; // 發送開始位
}
/*
** 函數名稱:位元組寫函數
**/
void EEPROM_read(unsigned char high_Address,unsigned char low_Address)
{
while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent
UCB0CTL1 |= UCTXSTT + UCTR; // 發送起始位,確定為寫
UCB0TXBUF = high_Address; // 發送地址位高位
while((IFG2 & UCB0TXIFG)==0); // 判斷是否發送完畢
UCB0TXBUF = low_Address; // 發送地址位低位
while((IFG2 & UCB0TXIFG)==0); // 判斷是否發送完畢
UCB0CTL1 &= ~UCTR; // 確定為接收
while (UCB0CTL1 & UCTXSTP); //
UCB0CTL1 |=UCTXSTT ;
while((UCB0CTL1 & UCTXSTT)==1);
for(unsigned char i=0x0;i<0x2f;i++); // 延時確定數據已經被發送出去
UCB0CTL1 |=UCTXSTP + UCTXNACK; // 發送停止位和NACK位
}
/*
** 函數名稱:接收中斷函數
**/
// USCI_B0 Data ISR
#pragma vector = USCIAB0TX_VECTOR
__interrupt void USCIAB0TX_ISR(void)
{
RXData = UCB0RXBUF; // Get RX data
Int_char(RXData);
LCD12864_gotoXY(2,0); //第2行,第1列顯示
LCD12864_sendstr(Result);
/*
key_code[0]=RXData%10+'0';
key_code[1]=0;
LCD12864_gotoXY(1,0); //第1行,第1列顯示
LCD12864_sendstr(key_code);
*/
// __bic_SR_register_on_exit(CPUOFF); // Exit LPM0
}
void Init_UART()
{
P3OUT &= ~(BIT4+BIT5+BIT6+BIT7);
P3SEL = 0xF0; // P3.4,5,6,7 = USCI_A0 TXD/RXD USCI_A1 TXD/RXD
UCA0CTL1 |= UCSSEL_1; // CLK = ACLK
UCA0BR0 = 0x03; // 32kHz/9600 = 3.41
UCA0BR1 = 0x00; //
UCA0MCTL = UCBRS1 + UCBRS0; // Molation UCBRSx = 3
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt
UCA1CTL1 |= UCSSEL_1; // CLK = ACLK
UCA1BR0 = 0x03; // 32kHz/9600 = 3.41
UCA1BR1 = 0x00; //
UCA1MCTL = UCBRS1 + UCBRS0; // Molation UCBRSx = 3
UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
UC1IE |= UCA1RXIE; // Enable USCI_A0 RX interrupt
_BIS_SR(GIE); //使能中斷
}
void Init_ADC()
{
ADC12CTL0 = SHT0_2 + ADC12ON; // Set sampling time, turn on ADC12
ADC12CTL1 = SHP; // Use sampling timer
ADC12IE = 0x01; // Enable interrupt
ADC12CTL0 |= ENC; // Conversion enabled
P6DIR &= 0x01; // P6.0, i/p
P6SEL |= 0x01; // P6.0-ADC option select
_BIS_SR(GIE); //使能中斷
}
void Start_ADC()
{
ADC12CTL0 |= ADC12SC; // Start convn, software controlled
}
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = UCA0RXBUF; // TX -> RXed character
LCD12864_sendbyte(iDat,UCA0RXBUF);
}
#pragma vector=USCIAB1RX_VECTOR
__interrupt void USCI1RX_ISR(void)
{
while (!(UC1IFG&UCA1TXIFG)); // USCI_A0 TX buffer ready?
UCA1TXBUF = UCA1RXBUF; // TX -> RXed character
LCD12864_sendbyte(iDat,UCA0RXBUF);
//UCA1TXBUF = 'z';
}
// ADC12 interrupt service routine
#pragma vector=ADC12_VECTOR
__interrupt void ADC12_ISR (void)
{
int i=ADC12MEM0;
Int_char(i);
LCD12864_gotoXY(2,0); //第1行,第1列顯示
LCD12864_sendstr(Result);
/*
key_code[0] =i/1000+'0';
key_code[1] =i/100%10+'0';
key_code[2] =i/10%10+'0';
key_code[3] =i%10+'0';
key_code[4] =0;
LCD12864_gotoXY(1,0); //第1行,第1列顯示
LCD12864_sendstr(key_code);
*/
}
void Init_all()
{
LCD12864_initial(); //LCD初始化,包含了數碼管和LED燈初始化
P7DIR=0x0F; //鍵盤掃描初始化
P7REN=0xF0; //輸入上下拉電阻使能,輸出上下拉不使能
P7OUT=0xF0; //輸入上拉
Init_UART(); //串口初始化
Init_compa(); //比較器初始化
Init_ADC(); //ADC初始化
Init_IIC(); //IIC初始化
}
void Test_Led()
{
unsigned char i=0;
LCD12864_gotoXY(1,0); //第1行,第1列顯示
LCD12864_sendstr("1.Test_LED");
for(;i<16;i++)
{
P8OUT=0xF0|i;
Delayms(50);
}
}
void Test_Seg()
{
int i;
LCD12864_gotoXY(1,0); //第1行,第1列顯示
LCD12864_sendstr("2.Test_SEG");
for(i=0;i<500;i++)
{
//4,3,2,1
P1OUT&=~0x02;
P1OUT|=0x10|0x08|0x04;
P5OUT=Seg_Data[9]; //清楚數碼管顯示
Delayms(1);
P1OUT&=~0x04;
P1OUT|=0x10|0x08|0x02;
P5OUT=Seg_Data[8]; //清楚數碼管顯示
Delayms(1);
P1OUT&=~0x08;
P1OUT|=0x10|0x04|0x02;
P5OUT=Seg_Data[7]; //清楚數碼管顯示
Delayms(1);
P1OUT&=~0x10;
P1OUT|=0x08|0x04|0x02;
P5OUT=Seg_Data[6]; //清楚數碼管顯示
Delayms(1);
}
P5OUT=0x00; //熄滅所有數碼管
}
void Test_Key()
{
unsigned char i=0;
LCD12864_gotoXY(1,0); //第1行,第1列顯示
LCD12864_sendstr("3.Test_KEY");
LCD12864_gotoXY(2,0); //第2行,第1列顯示
LCD12864_sendstr("按鍵:");
for(;i<16;i++)
{
Int_char(Get_Keycode());
LCD12864_gotoXY(2,3);
LCD12864_sendstr(" ");
LCD12864_gotoXY(2,3);
LCD12864_sendstr(Result);
Delayms(100); //防抖
}
}
void Test_Uart()
{
LCD12864_gotoXY(1,0); //第1行,第1列顯示
LCD12864_sendstr("4.Test_UART");
LCD12864_gotoXY(2,0); //第2行,第1列顯示
}
void Test_Compa()
{
LCD12864_gotoXY(1,0); //第1行,第1列顯示
LCD12864_sendstr("5.Test_COMPA");
}
void Test_ADC()
{
int i=0;
LCD12864_gotoXY(1,0); //第1行,第1列顯示
LCD12864_sendstr("6.Test_ADC");
for(;i<200;i++)
{
Start_ADC();
Delayms(10);
}
}
void Test_IIC()
{
LCD12864_gotoXY(1,0); //第1行,第1列顯示
LCD12864_sendstr("7.Test_IIC");
EEPROM_Write(0x00,0x40,7); // 位元組寫
Delayms(10);
EEPROM_read(0x00,0x40);
}
void main( void )
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;//關閉看門狗
Init_all();
while(1){
Test_Led(); //1.測試LED
LCD12864_gotoXY(2,0); //第1行,第1列顯示
LCD12864_sendstr("請按16鍵!");
while(!(Get_Keycode()==15)); //按下最後一鍵測試下一個例子
LCD12864_clear();
Test_Seg(); //2.測試數碼管
LCD12864_gotoXY(2,0); //第1行,第1列顯示
LCD12864_sendstr("請按16鍵!");
while(!(Get_Keycode()==15)); //按下最後一鍵測試下一個例子
LCD12864_clear();
Test_Key(); //3.測試按鍵掃描
LCD12864_gotoXY(2,0); //第1行,第1列顯示
LCD12864_sendstr("請按16鍵!");
while(!(Get_Keycode()==15)); //按下最後一鍵測試下一個例子
LCD12864_clear();
LCD12864_gotoXY(3,0); //第3行,第1列顯示
LCD12864_sendstr("請按16鍵!");
Test_Uart(); //4.測試串口
while(!(Get_Keycode()==15)); //按下最後一鍵測試下一個例子
LCD12864_clear();
Test_Compa(); //5.測試比較器
LCD12864_gotoXY(2,0); //第2行,第1列顯示
LCD12864_sendstr("請按16鍵!");
while(!(Get_Keycode()==15)); //按下最後一鍵測試下一個例子
LCD12864_clear();
Test_ADC(); //6.測試ADC
LCD12864_gotoXY(3,0); //第3行,第1列顯示
LCD12864_sendstr("請按16鍵!");
while(!(Get_Keycode()==15)); //按下最後一鍵測試下一個例子
LCD12864_clear();
Test_IIC(); //7.測試IIC
Delayms(100);
LCD12864_gotoXY(3,0); //第3行,第1列顯示
LCD12864_sendstr("測試完成");
while(!(Get_Keycode()==15)); //按下最後一鍵測試下一個例子
LCD12864_clear();
}
}