代码(STC15F104W@11.0592MHz):
#include <STC15F2K60S2.H>
#include <intrins.h>
#define IN P30
#define TXD P31
#define RXD P32
#define Buzzer P33 //定义蜂鸣器IO口
#define LCD12864_SID P34 //定义LCD12864时钟IO口
#define LCD12864_SCLK P35 //定义LCD12864数据IO口
//define baudrate const
//BAUD = 256 - FOSC/3/BAUDRATE/M (1T:M=1; 12T:M=12)
//NOTE: (FOSC/3/BAUDRATE) must be greater then 98, (RECOMMEND GREATER THEN 110)
//#define BAUD 0xF400 // 1200bps @ 11.0592MHz
//#define BAUD 0xFA00 // 2400bps @ 11.0592MHz
//#define BAUD 0xFD00 // 4800bps @ 11.0592MHz
#define BAUD 0xFE80 // 9600bps @ 11.0592MHz
//#define BAUD 0xFF40 //19200bps @ 11.0592MHz
//#define BAUD 0xFFA0 //38400bps @ 11.0592MHz
//#define BAUD 0xEC00 // 1200bps @ 18.432MHz
//#define BAUD 0xF600 // 2400bps @ 18.432MHz
//#define BAUD 0xFB00 // 4800bps @ 18.432MHz
//#define BAUD 0xFD80 // 9600bps @ 18.432MHz
//#define BAUD 0xFEC0 //19200bps @ 18.432MHz
//#define BAUD 0xFF60 //38400bps @ 18.432MHz
//#define BAUD 0xE800 // 1200bps @ 22.1184MHz
//#define BAUD 0xF400 // 2400bps @ 22.1184MHz
//#define BAUD 0xFA00 // 4800bps @ 22.1184MHz
//#define BAUD 0xFD00 // 9600bps @ 22.1184MHz
//#define BAUD 0xFE80 //19200bps @ 22.1184MHz
//#define BAUD 0xFF40 //38400bps @ 22.1184MHz
//#define BAUD 0xFF80 //57600bps @ 22.1184MHz
#define Write_Command 0xf8
#define Write_Data 0xfa
#define Read_Command 0xfc
#define Read_Data 0xfe
#define Setting_Basic_Instruction_Set 0x30
#define Setting_Extended_Instruction_Set_Drawing_Off 0x34
#define Setting_Extended_Instruction_Set_Drawing_On 0x36
#define Clear_Display 0x01
#define Entry_Mode_Cursor_Left 0x04
#define Entry_Mode_Entire_Right 0x05
#define Entry_Mode_Cursor_Right 0x06
#define Entry_Mode_Entire_Left 0x07
#define Display_Off 0x08
#define Display_On_Cursor_Off_Inverse_Off 0x0c
#define Display_On_Cursor_Off_Inverse_On 0x0d
#define Display_On_Cursor_On_Inverse_Off 0x0e
#define Display_On_Cursor_On_Inverse_On 0x0f
#define Cursor_Move_Left 0x10
#define Cursor_Move_Right 0x14
#define Display_Move_Left 0x18
#define Display_Move_Right 0x1c
bit TING,RING,TEND,REND;
unsigned char TBUF,RBUF,TDAT,RDAT,TCNT,RCNT,TBIT,RBIT,temp;
unsigned int pma,pmb,pmc;
unsigned char code Display_Hex[16]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};
unsigned char code Display_Data1[64]=
{
" PM2.5 Test " //0x80
" 初始化中 " //0x90
" …… " //0x88
"Designed by: STI" //0x98
};
unsigned char code Display_Data2[64]=
{
" PM1.0=0000 " //0x80
" PM2.5=0000 " //0x90
" PM10 =0000 " //0x88
"空气质量 " //0x98
};
/*----------------------------延时10us@STC-Y5@11.0592MHz----------------------------*/
void Delay_10us(void)
{
unsigned char i;
_nop_();
_nop_();
i=25;
while(--i);
}
/*----------------------------延时x10us----------------------------*/
void Delay_x10us(unsigned char x)
{
while(x--)
Delay_10us();
}
/*----------------------------延时10ms@STC-Y5@11.0592MHz----------------------------*/
void Delay_10ms(void)
{
unsigned char i,j;
i=108;
j=145;
do
{
while(--j);
}while(--i);
}
//initial UART module variable
void UART_INIT(void)
{
TING=0;
RING=0;
TEND=1;
REND=0;
TCNT=0;
RCNT=0;
}
//Receive UART data
unsigned char UART_Receive(void)
{
while(!REND);
REND=0;
return RBUF;
}
//Send UART data
//void UART_Send(unsigned char dat)
//{
// while(!TEND);
// TEND=0;
// TBUF=dat;
// TING=1;
//}
/*----------------------------写1字节命令或数据----------------------------*/
void LCD12864_Write_Byte(unsigned char temp)
{
unsigned char i;
for(i=0;i<8;i++)
{
if((temp<<i)&0x80)
LCD12864_SID=1;
else
LCD12864_SID=0;
LCD12864_SCLK=0;
LCD12864_SCLK=1;
}
}
/*----------------------------传送数据或者命令----------------------------*/
void LCD12864_Write(unsigned char Command,unsigned char temp)
{
LCD12864_Write_Byte(Command);
LCD12864_Write_Byte(temp&0xf0);
LCD12864_Write_Byte((temp<<4)&0xf0);
}
/*----------------------------清空GDRAM----------------------------*/
void Clear_GDRAM(void)
{
unsigned char i,j,k;
LCD12864_Write(Write_Command,Setting_Extended_Instruction_Set_Drawing_Off);
k=0x80;
for(i=0;i<32;i++)
{
LCD12864_Write(Write_Command,k++);
LCD12864_Write(Write_Command,0x80);
for(j=0;j<16;j++)
{
LCD12864_Write(Write_Data,0x00);
}
}
k=0x80;
for(i=0;i<32;i++)
{
LCD12864_Write(Write_Command,k++);
LCD12864_Write(Write_Command,0x88);
for(j=0;j<16;j++)
{
LCD12864_Write(Write_Data,0x00);
}
}
LCD12864_Write(Write_Command,Setting_Extended_Instruction_Set_Drawing_On);
}
/*----------------------------整页显示字符----------------------------*/
void Display_Text(unsigned char code *addr)
{
unsigned char i;
LCD12864_Write(Write_Command,Setting_Basic_Instruction_Set);
LCD12864_Write(Write_Command,0x80); //设置DDRAM地址
Delay_10us();
for(i=0;i<16;i++)
{
LCD12864_Write(Write_Data,*addr);
addr++;
}
LCD12864_Write(Write_Command,0x90); //设置DDRAM地址
Delay_10us();
for(i=0;i<16;i++)
{
LCD12864_Write(Write_Data,*addr);
addr++;
}
LCD12864_Write(Write_Command,0x88); //设置DDRAM地址
Delay_10us();
for(i=0;i<16;i++)
{
LCD12864_Write(Write_Data,*addr);
addr++;
}
LCD12864_Write(Write_Command,0x98); //设置DDRAM地址
Delay_10us();
for(i=0;i<16;i++)
{
LCD12864_Write(Write_Data,*addr);
addr++;
}
}
/*----------------------------指定位置显示字符----------------------------*/
void Display_Data(unsigned char x,unsigned char y,unsigned char Data1,unsigned char Data2)
{
LCD12864_Write(Write_Command,Setting_Basic_Instruction_Set);
switch(y)
{
case 0:
LCD12864_Write(Write_Command,0x80+x); //设置DDRAM地址
Delay_10us();
LCD12864_Write(Write_Data,Data1);
LCD12864_Write(Write_Data,Data2);
break;
case 1:
LCD12864_Write(Write_Command,0x90+x); //设置DDRAM地址
Delay_10us();
LCD12864_Write(Write_Data,Data1);
LCD12864_Write(Write_Data,Data2);
break;
case 2:
LCD12864_Write(Write_Command,0x88+x); //设置DDRAM地址
Delay_10us();
LCD12864_Write(Write_Data,Data1);
LCD12864_Write(Write_Data,Data2);
break;
case 3:
LCD12864_Write(Write_Command,0x98+x); //设置DDRAM地址
Delay_10us();
LCD12864_Write(Write_Data,Data1);
LCD12864_Write(Write_Data,Data2);
break;
}
}
/*----------------------------初始化12864----------------------------*/
void LCD12864_Init(void)
{
Delay_10ms(); //40mS延时
Delay_10ms();
Delay_10ms();
Delay_10ms();
LCD12864_Write(Write_Command,Setting_Basic_Instruction_Set);
Delay_x10us(10); //100uS延时
LCD12864_Write(Write_Command,Setting_Basic_Instruction_Set);
Delay_x10us(4); //40uS延时
LCD12864_Write(Write_Command,Clear_Display); //显示光标闪烁完全关闭
Delay_x10us(10); //100uS延时
LCD12864_Write(Write_Command,Clear_Display); //清除显示
Delay_10ms(); //10mS延时
LCD12864_Write(Write_Command,Entry_Mode_Cursor_Right); //光标右移模式
Delay_x10us(10); //100uS延时
LCD12864_Write(Write_Command,Display_On_Cursor_Off_Inverse_Off); //开显示,无光标,光标不闪烁
Delay_x10us(10); //100uS延时
Clear_GDRAM(); //清空GDRAM
Delay_x10us(10); //100uS延时
}
void Init(void)
{
TMOD=0x00; //设置定时器0为16位自动重载模式
AUXR=0x80; //设置定时器0时钟为1T模式
TL0=BAUD; //设置定时器0初值
TH0=BAUD>>8; //设置定时器0初值
ET0=1; //打开定时器0中断
PT0=1; //设置定时器0高优先级
EA=1; //打开总中断
TR0=1; //定时器0开始计时
P3M0=0x08;
P3M1=0x00;
UART_INIT();
LCD12864_Init();
}
/*----------------------------主函数----------------------------*/
void main(void)
{
Init();
Display_Text(Display_Data1);
while(1)
{
if(REND)
{
temp=UART_Receive();
if(temp==0x42)
{
temp=UART_Receive();
temp=UART_Receive();
temp=UART_Receive();
temp=UART_Receive();
temp=UART_Receive();
temp=UART_Receive();
temp=UART_Receive();
temp=UART_Receive();
temp=UART_Receive();
temp=UART_Receive();
pma=temp;
pma=pma<<8;
temp=UART_Receive();
pma=pma+temp;
temp=UART_Receive();
pmb=temp;
pmb=pmb<<8;
temp=UART_Receive();
pmb=pmb+temp;
temp=UART_Receive();
pmc=temp;
pmc=pmc<<8;
temp=UART_Receive();
pmc=pmc+temp;
temp=UART_Receive();
temp=UART_Receive();
temp=UART_Receive();
temp=UART_Receive();
temp=UART_Receive();
temp=UART_Receive();
temp=UART_Receive();
temp=UART_Receive();
if(temp==0xd2&&pma==0x006b&&pmb==0x008c&&pmc==0x009e)
{
Display_Text(Display_Data1);
}
else
{
Display_Text(Display_Data2);
Display_Data(4,0,0x3d,Display_Hex[pma%10000/1000]);
Display_Data(5,0,Display_Hex[pma%1000/100],Display_Hex[pma%100/10]);
Display_Data(6,0,Display_Hex[pma%10],0x20);
Display_Data(4,1,0x3d,Display_Hex[pma%10000/1000]);
Display_Data(5,1,Display_Hex[pmb%1000/100],Display_Hex[pmb%100/10]);
Display_Data(6,1,Display_Hex[pmb%10],0x20);
Display_Data(4,2,0x3d,Display_Hex[pmc%10000/1000]);
Display_Data(5,2,Display_Hex[pmc%1000/100],Display_Hex[pmc%100/10]);
Display_Data(6,2,Display_Hex[pmc%10],0x20);
if(pmb>=0&&pmb<=35)
{
Display_Data(4,3,0xd3,0xc5);
Display_Data(5,3,0x20,0x20);
Display_Data(6,3,0x20,0x20);
Display_Data(7,3,0x20,0x20);
}
else if(pmb>=36&&pmb<=75)
{
Display_Data(4,3,0xc1,0xbc);
Display_Data(5,3,0x20,0x20);
Display_Data(6,3,0x20,0x20);
Display_Data(7,3,0x20,0x20);
}
else if(pmb>=76&&pmb<=115)
{
Display_Data(4,3,0xc7,0xe1);
Display_Data(5,3,0xb6,0xc8);
Display_Data(6,3,0xce,0xdb);
Display_Data(7,3,0xc8,0xbe);
}
else if(pmb>=116&&pmb<=150)
{
Display_Data(4,3,0xd6,0xd0);
Display_Data(5,3,0xb6,0xc8);
Display_Data(6,3,0xce,0xdb);
Display_Data(7,3,0xc8,0xbe);
}
else if(pmb>=151&&pmb<=250)
{
Display_Data(4,3,0xd6,0xd8);
Display_Data(5,3,0xb6,0xc8);
Display_Data(6,3,0xce,0xdb);
Display_Data(7,3,0xc8,0xbe);
}
else if(pmb>=251&&pmb<=999)
{
Display_Data(4,3,0xd1,0xcf);
Display_Data(5,3,0xd6,0xd8);
Display_Data(6,3,0xce,0xdb);
Display_Data(7,3,0xc8,0xbe);
}
else if(pmb>=1000)
{
Display_Data(4,3,0xb1,0xac);
Display_Data(5,3,0xb1,0xed);
Display_Data(6,3,0xce,0xdb);
Display_Data(7,3,0xc8,0xbe);
}
}
}
}
if(IN==0)
IAP_CONTR=0x60;
}
}
//Timer interrupt routine for UART
void timer0(void) interrupt 1
{
if(RING)
{
if(--RCNT==0)
{
RCNT=3; //reset send baudrate counter
if(--RBIT==0)
{
RBUF=RDAT; //save the data to RBUF
RING=0; //stop receive
REND=1; //set receive completed flag
}
else
{
RDAT>>=1;
if(RXD)RDAT|=0x80; //shift RX data to RX buffer
}
}
}
else if(!RXD)
{
RING=1; //set start receive flag
RCNT=4; //initial receive baudrate counter
RBIT=9; //initial receive bit number (8 data bits + 1 stop bit)
}
if(--TCNT==0)
{
TCNT=3; //reset send baudrate counter
if(TING) //judge whether sending
{
if(TBIT==0)
{
TXD=0; //send start bit
TDAT=TBUF; //load data from TBUF to TDAT
TBIT=9; //initial send bit number (8 data bits + 1 stop bit)
}
else
{
TDAT>>=1; //shift data to CY
if(--TBIT==0)
{
TXD=1;
TING=0; //stop send
TEND=1; //set send completed flag
}
else
{
TXD=CY; //write CY to TX port
}
}
}
}
}