这周在上次实现的电子钟(51单片机初学实践:用DS1302模块和LCD1602显示屏实现电子钟)的基础上作了以下2点改进:1、将LCD1602屏幕更换为1.44寸 TFT显示屏
主要考虑是TFT显示屏可以使用不同字体和颜色,更方便定制显示界面
2、将STC89C52RC单片机更换为STC12C5A60S2单片机
首先是空间更大,STC12C5A60S2单片机(60K bytes flash ROM, 1280 bytes data RAM),STC89C52RC单片机(8K bytes flash ROM, 512 bytes data RAM)
其次STC12C5A60S2单片机有单独的SPI接口(P1.5 MOSI 和 P1.6 MISO),可以更好地驱动TFT显示屏
STC12C5A60S2单片机有10位ADC(P1.0 - P1.7),可以采集光敏电阻电压,自动调整TFT显示屏背光亮度
STC12C5A60S2单片机有专用PWM输出(P1.3 和 P1.4,可以很方便地调整TFT显示屏背光亮度
TFT显示屏效果:
从上到下依次为:年月日 星期几 时分秒 气温 光敏电阻电压
串口打印效果:
实物接线效果:
在实践过程中,有以下心得:
1、STC12C5A60S2单片机有专用的串口定时器,更方便设置波特率
- /* 串口配置函数,通信波特率 9600 */
- void UART1_Config()
- {
- PCON &= 0x7F; //波特率不倍速
- SCON = 0x50; //配置串口为模式1,允许发送和接收
- //9600bps@11.0592MHz
- BRT = 0xDC; //设定独立波特率发生器重装值
- AUXR |= 0x04; //独立波特率发生器时钟为Fosc,即1T
- AUXR |= 0x01; //串口1选择独立波特率发生器为波特率发生器
- AUXR |= 0x10; //启动独立波特率发生器
- EA = 1; //启用中断
- ES = 1; //启用串口中断
- }
复制代码
2、P3.2需要设置为推挽模式,以便更好地驱动显示屏背光
- #ifdef MCU_STC12
- //P3.2 set as push-pull output mode, for LCD backlight
- P3M1 &= ~(1<<2);
- P3M0 |= (1<<2);
- #endif
复制代码
3、ADC采样输入,需要用到P1.0和P1.1两个端口,P1.0用于测量TL431输出的参考电压2.5v,P1.1用于测量光敏电阻当前分压
- void ADC_Init()
- {
- P1ASF = 0x03; //选择P1.0和P1.1作为ADC采样输入
- // ADRJ=1时,10位A/D转换结果的高2位存放在ADC_RES的低2位中,低8位存放在ADC_RESL中
- AUXR1 |= 1<<2; //set ADRJ=1 : 10bit result = ADC_RES<<8 + ADC_RESL
- ADC_RES = 0;
- ADC_RESL = 0;
- ADC_CONTR = ADC_POWER | ADC_SPEEDLL; // 打开A/D转换器电源, 540个时钟周期转换一次
- Delay10us();
- }
- uint16 ADC_Get_Result(uint8 channel)
- {
- uint16 res;
- ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | channel;
- _nop_(); //Must wait before inquiry
- _nop_();
- _nop_();
- _nop_();
- while(!(ADC_CONTR & ADC_FLAG));
- ADC_CONTR &= ~ADC_FLAG;
- res = (ADC_RES & 0x03) << 8;
- res += ADC_RESL;
- Delay10us();
- Delay10us();
- return res;
- }
复制代码
TL431和光敏电阻接线示意
光敏电阻的特点是光照越强阻值越小,分压降低,而在弱光环境则是阻值变大,分压升高,如下二图所示
可以根据这个特点自动调整显示屏背光强度
4、PWM输出
不需要修改频率,直接设置为SysClk/12
PCA模块工作模式设定为8位PWM,无中断
占空比调整通过设置不同的CCAP1L/H值来实现
- <blockquote>// 1.3和1.4口 PWM占空比,数值越大,占空比越小
复制代码
5、在TFT屏幕上显示字符
需要注意12x16和12x24这种字符点阵数据,由于12不是8的整数倍,实际存储16bit,使用时,需要跳过最后4个填充bit
//采用设置窗口方法填充12x24点阵数字
void Display_Digit_12x24(uint8 x, uint8 y, uint16 fc, uint16 bc, uint8 idx)
{
uint8 i,j,k;
LCD_Set_Region(x, y, 12, 24);
for(i=0; i<3*16; i++)
{
if(1 == i%2) k = 4;
else k = 8;
for(j=0; j<k; j++)
{
if(digit12x24[idx][ i]&(0x80>>j))
{
SPI_Write_Word(fc);
}
else
{
if (fc != bc)
{
SPI_Write_Word(bc);
}
}
}
}
}
6、main函数内容:
- void main()
- {
- int8 slen = 0;
- uint8 pdata uart_cmd_buf[64] = {0};
- DS18B20_Start();
- UART1_Config(); // 9600 baud
- Timer0Init(); //T0定时10ms
- DS1302_Init(); //初始化RTC时钟
- ADC_Init();
- #ifdef MCU_STC12
- //P3.2 set as push-pull output mode, for LCD backlight
- P3M1 &= ~(1<<2);
- P3M0 |= (1<<2);
- #endif
- SPI_Init();
- LCD_Init();
- PWM_Init();
- delay_ms(500);
- LCD_Show_Format();
- while(1)
- {
-
- Uart_Cmd_Check(&uart_cmd_buf, sizeof(uart_cmd_buf)-1);
- if (timer_flag_250ms) //每250ms读取依次时间
- {
- ReadAndShowRtc();
- timer_flag_250ms = 0;
- }
- if (timer_flag_5s) //每隔5s执行以下分支
- {
- //printf(">>>===\r\n");
- ReadAndShowTemperature(-5);
-
- ReadAndShowPhotoresistorVoltage();
- timer_flag_5s = 0;
- }
- }
- }
复制代码
STC12C5A60S2单片机手册下载地址(点替换成.):www点stcmcudata点com/datasheet/stc/STC-AD-PDF/STC12C5A60S2.pdf
1.44寸TFT(ST7735)显示屏资料(点替换成.):www点lcdwiki点com/zh/1.44inch_SPI_Module_ST7735S_SKU:MSP1443
完整代码见附件,文件列表如图所示:
以上代码使用最小系统和面包板调试,接线简单,具体端口可参看config.h
初学单片机,难免有错漏之处,还请各位坛友不吝赐教。
DS1302_UART_ST7735_STC12C5A60S2.7z
(2.34 MB, 下载次数: 222)
|