|
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include "lcd12864.h"
- #ifdef LCD12864_DEV_DRIVER
- sbit DQ = DS18B20_DQ_PIN
- static uint16_t clock_ticks = 0;
- static bool_t second_flag = 0;
- static uint8_t pos_x = 0;
- static uint8_t pos_y = 0;
- static uint8_t pos_x_befor = 0;
- static uint8_t pos_y_befor = 0;
- static idata int16_t temperature;
- static idata float temp_display;
- static idata uint8_t display_buf[8];
- static void ds18b20_delay(uint16_t i)
- {
- while( i-- );
- }
- static bool_t ds18b20_reset(void) /* 初始化函数 */
- {
- uint8_t x = 0;
-
- DQ = 1; //DQ复位
- ds18b20_delay(8); //稍做延时
- DQ = 0; //单片机将DQ拉低
- ds18b20_delay(80); //精确延时 大于 480us
- DQ = 1; //拉高总线
- ds18b20_delay(14);
- x = DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
- ds18b20_delay(20);
- if(x == 0){
- return TRUE;
- }else{
- return FALSE;
- }
- }
- static uint8_t ds18b20_read_one_char(void)/* 读一个字节 */
- {
- uint8_t i=0;
- uint8_t dat = 0;
-
- for (i=8;i>0;i--){
- DQ = 0; /* 给脉冲信号 */
- dat>>=1;
- DQ = 1; /* 给脉冲信号 */
- if(DQ)
- dat|=0x80;
- ds18b20_delay(4);
- }
-
- return dat;
- }
- static uint8_t ds18b20_write_one_char(uint8_t dat)/* 写一个字节 */
- {
- uint8_t i=0;
-
- for (i=8; i>0; i--){
- DQ = 0;
- DQ = dat&0x01;
- ds18b20_delay(5);
- DQ = 1;
- dat>>=1;
- }
- return dat;
- }
- int16_t ds18b20_read_temperature(void)/* 读取温度, 返回的温度值 *10, 即一位小数 */
- {
- uint8_t a = 0;
- uint8_t b = 0;
- int16_t t = 0;
- bool_t is_negative_temp = 0;
-
- __disable_irq();
-
- ds18b20_reset();
- ds18b20_write_one_char(0xCC); /* 跳过读序号列号的操作 */
- ds18b20_write_one_char(0x44); /* 启动温度转换 */
- ds18b20_delay(100);
- ds18b20_reset();
-
- ds18b20_write_one_char(0xCC); /* 跳过读序号列号的操作 */
- ds18b20_write_one_char(0xBE); /* 读取温度寄存器等(共可读9个寄存器) 前两个就是温度 */
- a = ds18b20_read_one_char();
- b = ds18b20_read_one_char();
-
- __enable_irq();
- if( b > 0x7f ) /* 最高位为1 时温度是负 */
- {
- a = ~a + 1;
- b = ~b;
- is_negative_temp = 1;
- }
- t = a >> 4;
- t += b << 4;
- a = (a&0x0f)*10 >> 4;
- t *= 10;
- t += a;
-
- if(is_negative_temp){
- t = -t;
- }
-
- return t;
- }
- void ds18b20_init(void)
- {
- ds18b20_reset();
- ds18b20_write_one_char(0xcc);//忽略ROM指令
- ds18b20_write_one_char(0x4e);//写暂存器指令
- ds18b20_write_one_char(0); //TH值未使用
- ds18b20_write_one_char(0); //TL值未使用
- ds18b20_write_one_char(0x3f);// 采用bit数。
- //0x1f : 0.5000°C 转换时间93.75ms
- //0x3f : 0.2000°C 转换时间187.5ms
- //0x5f : 0.1250°C 转换时间375ms
- //0x7f : 0.0625°C 转换时间750ms
- ds18b20_read_temperature(); /* 第一次读取值错误,丢弃 */
- }
- static void draw_coord(void)/* 画坐标 */
- {
- pos_x = 0;
- pos_y = 0;
- pos_x_befor = 0;
- pos_y_befor = 0;
- lcd12864_clear_display(0);
-
- lcd12864_draw_dotted_line(0,63, 0, 0);
- lcd12864_draw_dotted_line(0,32,127,32);
- lcd12864_draw_dotted_line(0, 63,127, 63);
- lcd12864_show_string(0, 80, "T:0");
- }
- void Delay500ms() //@11.0592MHz
- {
- unsigned char i, j, k;
- _nop_();
- i = 4;
- j = 129;
- k = 119;
- do
- {
- do
- {
- while (--k);
- } while (--j);
- } while (--i);
- }
- void main(void)
- {
- SCON = 0x50; /* 8位数据,可变波特率 */
- TMOD &= 0x0f; /* 设定定时器1为16位自动重装方式 */
- TMOD |= 0x20; /* 设定定时器1为16位自动重装方式 */
- PCON = 0x00; /* 波特率不加倍 */
- TH1 = 0xFD; /* 设定定时初值 */
- TL1 = 0xFD; /* 设定定时初值 */
- TR1 = 1; /* 启动定时器1 */
- REN = 1; /* 使能接收 */
- ES = 1; /* 打开串口中断 */
-
- TMOD &= 0xF0; //设置定时器模式
- TMOD |= 0x01; //设置定时器模式
- TL0 = 0x00; //设置定时初值,50ms中断
- TH0 = 0x4C; //设置定时初值
- TF0 = 0; //清除TF0标志
- TR0 = 1; //定时器0开始计时
- ET0 = 1; //允许定时/计数器0中断
-
- ds18b20_init();
- lcd12864_init();
- __enable_irq();
- draw_coord();
- second_flag = 1;
- ds18b20_read_temperature();
- Delay500ms();
- ds18b20_read_temperature();
- Delay500ms();
- while(1){
- if(second_flag == 1){
- second_flag = 0;
- if(pos_x == 128){
- draw_coord();
- }
-
- temperature = ds18b20_read_temperature();
- temp_display = temperature / 10.0;
- sprintf(display_buf, "%.1f", temp_display);
- lcd12864_show_string(0, 96, " ");
- lcd12864_show_string(0, 96, display_buf);
- if(temperature > 630){
- temperature = 630;
- }else if(temperature < 0){
- temperature = 0;
- }
-
- pos_y = temperature / 10;
- pos_y = 63 - pos_y;
-
- if(pos_x == 0){
- pos_x_befor = 0;
- pos_y_befor = pos_y;
- }
- lcd12864_draw_line(pos_x_befor, pos_y_befor, pos_x, pos_y);
- pos_x_befor = pos_x;
- pos_y_befor = pos_y;
- pos_x++;
- }
- }
- }
- void timer0() interrupt 1
- {
- TL0 = 0x00;//重新装载初值, 50ms中断
- TH0 = 0x4c;
-
- clock_ticks++;
- if(clock_ticks == 20){
- clock_ticks = 0;
- second_flag = 1;
- }
- }
- sbit RST = LCD12864_RST;
- sbit E = LCD12864_EN;
- sbit RW = LCD12864_RW;
- sbit DI = LCD12864_DI;
- sbit CS1 = LCD12864_CS1;
- sbit CS2 = LCD12864_CS2;
- #define LCDPORT P0
- #define LCDSTARTROW 0xC0 /* 设置起始行指令 */
- #define LCDPAGE 0xB8 /* 设置页指令 */
- #define LCDLINE 0x40 /* 设置列指令 */
- #define ASCII_CODE_12864_ELEMENT_NUM ( 67 )
- extern ascii_12864 code ascii_code_12864[];
- /*---------------------------------------------------------------------------*/
- static bool_t lcd12864_is_busy(void)
- {
- uint8_t state = 0;
- bool_t busy;
-
- LCDPORT = 0xFF;
- RW = 1;
- DI = 0;
- E = 1;
- E = 0;
- E = 1;/* E的下降沿,然后E持续拉高读才有效 */
- state = LCDPORT;
- E = 0;
- busy = (bool_t)(state>>7);
- return busy;
- }
- /*---------------------------------------------------------------------------*/
- static void lcd12864_write_data(uint8_t ucData)
- {
- uint16_t timeout;
- timeout = 0;
- while(lcd12864_is_busy()){
- timeout++;
- if(timeout > 0xff){
- break;
- }
- }
- LCDPORT = 0xFF;
- RW = 0;
- DI = 1;
- LCDPORT = ucData;
- E = 1;
- E = 0;
- }
- /*---------------------------------------------------------------------------*/
- static void lcd12864_write_cmd(uint8_t ucCMD)
- {
- uint16_t timeout;
- timeout = 0;
- while(lcd12864_is_busy()){
- timeout++;
- if(timeout > 0xff){
- break;
- }
- }
- LCDPORT = 0xFF;
- RW = 0;
- DI = 0;
- LCDPORT = ucCMD;
- E = 1;
- E = 0;
- }
- /*---------------------------------------------------------------------------*/
- void lcd12864_init( void )
- {
- CS1 = 1;
- CS2 = 1;
-
- lcd12864_write_cmd(0x38); /* 8位形式,两行字符 */
- lcd12864_write_cmd(0x0F); /* 开显示 */
- lcd12864_write_cmd(0x01); /* 清屏 */
- lcd12864_write_cmd(0x06); /* 画面不动,光标右移 */
- lcd12864_write_cmd(LCDSTARTROW); /* 设置起始行 */
- }
- /*---------------------------------------------------------------------------*/
- static void lcd12864_show_custom_row(uint8_t ucPage,uint8_t ucLine,uint8_t ucWidth,uint8_t *ucaRow)
- {
- uint8_t ucCount;
-
- if(ucLine < 64){
- CS1=1;
- CS2=0;
- lcd12864_write_cmd(LCDPAGE + ucPage);
- lcd12864_write_cmd(LCDLINE + ucLine);
- if( (ucLine + ucWidth) < 64 ){
- for(ucCount = 0; ucCount < ucWidth; ucCount++){
- lcd12864_write_data(*(ucaRow + ucCount));
- }
- }
- else{
- for(ucCount = 0; ucCount < (64 - ucLine); ucCount++){
- lcd12864_write_data(*(ucaRow+ucCount));
- }
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
程序+proteus.zip
(167.24 KB, 下载次数: 123)
|
评分
-
查看全部评分
|