|
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
26cd79045bca48e137307bebb1eec6f6.png (14.38 KB, 下載次數: 99)
下載附件
2021-3-5 15:57 上傳
15ea771bf9730504f44caff0e9e3af70.png (55.77 KB, 下載次數: 87)
下載附件
2021-3-5 15:57 上傳
單片機源程序如下:
- #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)
2021-3-5 12:08 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|
評分
-
查看全部評分
|