好久沒用csdn寫文章了,目前主要的記錄都使用onenote,這次寫這個也主要是完成之前的一個未完成的事情。
ds18b20測溫,51就能完成,用dsp做純屬娛樂。當然,dsp與51之間的代碼有相似,也有差異。下面就開始詳細講解吧。
首先,ds18b20使用的是taobao購買的集成模塊,其結構以及電路如圖1所示:
圖1
之後大家要對ds18b20的工作時序進行詳細瞭解,不然。。。反正我吃過虧。具體時序在代碼中給出。
下面這段程序是整個程序的主函數,包含了 main以及IO口配置
/***************************************************
* Lcd12864: RS:GPIO0; RW:GND已經板載接地 ;EN:GPIO1 ;D0-D7:GPIO2-GPIO9
* DS18B20 DQ:GPIO40/A0
* 2019/06/15
***************************************************/
#include "DSP2833x_Project.h"
#include "lcd12864.h"
#include "ds18b20_para.h"
/********************
* 定義全局變量
********************/
#define uchar unsigned char
void init_port(void);
uchar Init_DS18B20();
uchar ReadOneChar(void);
void WriteOneChar(uchar dat);
float ReadTemperature();
void lcd_init(void);
void lcd_write_cmd(uchar cmd); //可以理解爲寫進去是分配的地址類似scanf
void lcd_write_dat(uchar dat); //同時
void LCD12864SetAddress_f( uchar x, uchar y ); //地址轉換
void show(uchar x, uchar y, uchar * data);
uchar table[7];
void main()
{
float tt;
int tt1;
InitSysCtrl();
init_port();
DINT;
InitPieCtrl(); //初始化中斷控制
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();//初始化中斷矢量表
lcd_init();
while (1)
{
tt=ReadTemperature();
tt1=tt*100+0.5;
//留兩個小數點就*100,+0.5是四捨五入,因爲C語言浮點數轉換爲整型的時候把小數點
//後面的數自動去掉,不管是否大於0.5,而+0.5之後大於0.5的就是進1了,小於0.5的就
//算加上0.5,還是在小數點後面。
table[0]=tt1/10000+0x30; //百位
table[1]=tt1%10000/1000+0x30;//十位
table[2]=tt1%1000/100+0x30;//個位
table[3]='.';
table[4]=tt1%100/10+0x30;//個位;
table[5]=tt1%10+0x30;//個位;
table[6]='\0';
show(0,0,table);
}
}
void init_port(void)
{
EALLOW;
GpioCtrlRegs.GPBPUD.bit.GPIO40 = 0; // 使能GPIO10 引腳內部上拉
GpioCtrlRegs.GPBMUX1.bit.GPIO40 =0; // 配置GPIO10爲通用I/O口
GpioCtrlRegs.GPBQSEL1.bit.GPIO40 = 0; // GPIO40與系統時鐘SYSCLKOUT 同步
//lcd12864 use
GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0; // 使能GPIO0 引腳內部上拉
GpioCtrlRegs.GPAPUD.bit.GPIO1 = 1; // 禁止GPIO1 引腳內部上拉
GpioCtrlRegs.GPAQSEL1.all = 0x0000; // GPIO0-GPIO15與系統時鐘SYSCLKOUT 同步
GpioCtrlRegs.GPADIR.all = 0x003FF;// 配置GPIO0-GPIO9爲輸出引腳
//輸出數據LCD_RW和LCD_EN清零
GpioDataRegs.GPADAT.bit.GPIO0 = 1;
GpioDataRegs.GPADAT.bit.GPIO1 = 0;
EDIS;
}
接下來,是主要部分,ds18b20的初始化和配置部分:
//這一部分是頭文件
/*
* ds18b20_para.h
*
* Created on: 2019年6月15日
* Author: wx
*/
#ifndef DS18B20_PARA_H_
#define DS18B20_PARA_H_
#include "DSP2833x_Project.h"
//---重定義關鍵詞---//
#ifndef uchar
#define uchar unsigned char
#endif
#define DQ_DIR GpioCtrlRegs.GPBDIR.bit.GPIO40 //方向
#define DQ GpioDataRegs.GPBDAT.bit.GPIO40//數值
uchar Init_DS18B20();
uchar ReadOneChar(void);
void WriteOneChar(uchar dat);
float ReadTemperature();
#endif /* DS18B20_PARA_H_ */
/*
* ds18b20_para.c
*
* Created on: 2019年6月15日
* Author: wx
*/
#include "ds18b20_para.h"
/*************************************************/
/* 初始化函數 */
/*************************************************/
uchar Init_DS18B20()
{
EALLOW;
DQ_DIR=1; //設置爲輸出狀態
EDIS;
DQ=0; //拉低電平
DELAY_US(650);//延遲650us
DQ=1; //釋放總線
DELAY_US(15);//延遲15us
EALLOW;
DQ_DIR=0; //設置爲輸入狀態
EDIS;
while (DQ)
{
DELAY_US(5000);//延遲5ms
return 0; //初始化失敗
}
return 1;//成功
}
/*************************************************/
/* 讀字節子函數 */
/*************************************************/
uchar ReadOneChar(void)
{
uchar i=0,dat=0;
for (i=8;i>0;i--)
{
EALLOW;
DQ_DIR=1; //設置爲輸出狀態
EDIS;
DQ=0;
DELAY_US(5);//延遲5us
DQ=1;
DELAY_US(6);//延遲6us,等待數據穩定
dat>>=1;//讀到數據後右移一位
EALLOW;
DQ_DIR=0; //設置爲輸入狀態
EDIS;
if(DQ)
dat|=0x80;//取回最高位數據
DELAY_US(60);//延遲60us
}
return dat;
}
/*************************************************/
/* 寫字節子函數 */
/*************************************************/
void WriteOneChar(uchar dat)
{
uchar i;
for(i=8;i>0;i--)
{
EALLOW;
DQ_DIR=1; //設置爲輸出狀態
EDIS;
DQ=0;
DELAY_US(5);//延遲5us
DQ=dat & 0x01;
DELAY_US(68);//延遲68us
DQ=1;
DELAY_US(5);//延遲5us
dat >>=1;
}
}
//讀取溫度
float ReadTemperature()
{
uchar a=0;
uchar b=0;
float t=0;
uchar temp;
Init_DS18B20();
DELAY_US(1000);//延遲1ms
WriteOneChar(0xCC); // 跳過讀序號列號的操作
WriteOneChar(0x44); // 啓動溫度轉換
Init_DS18B20();
DELAY_US(1000);//延遲1ms
WriteOneChar(0xCC); // 跳過讀序號列號的操作
WriteOneChar(0xbe); //跳過讀序號列號的操作
a=ReadOneChar();//低字節
b=ReadOneChar();//高字節
temp=b;
temp<<=8;
temp=temp|a;
t=temp*0.0625; //得到的是實際溫度
return(t);
}
ok,上面這些就是溫度的採集以及轉換部分,主要的功能已經實現,下面就是使用12864進行顯示:
/*
* lcd12864.h
*
* Created on: 2019年6月15日
* Author: wx
*/
#ifndef LCD12864_H_
#define LCD12864_H_
#include "DSP2833x_Project.h"
//---重定義關鍵詞---//
#ifndef uchar
#define uchar unsigned char
#endif
#define LCD_RS GpioDataRegs.GPADAT.bit.GPIO0 //RS--GPIO0引腳,數據/指令選擇端
//#define LCD_RW GpioDataRegs.GPADAT.bit.GPIO2 已經直接接地了
#define LCD_EN GpioDataRegs.GPADAT.bit.GPIO1 //EN--GPIO1引腳
#define LCD_DB GpioDataRegs.GPADAT.all
void lcd_init(void);
void lcd_write_cmd(uchar cmd); //可以理解爲寫進去是分配的地址類似scanf
void lcd_write_dat(uchar dat); //同時
void LCD12864SetAddress_f( uchar x, uchar y ); //地址轉換
void show(uchar x, uchar y, uchar * data);
#endif /* LCD12864_H_ */
/*
* lcd12864.c
*
* Created on: 2019年6月15日
* Author: Administrator
*/
#include "lcd12864.h"
void lcd_init(void)
{
DELAY_US(100000);//延遲100ms
lcd_write_cmd(0x30);//設置8位格式,2行,5x8
DELAY_US(200);//延遲200us
lcd_write_cmd(0x0c);//整體顯示,關光標,不閃爍
DELAY_US(200);//延遲200us
lcd_write_cmd(0x01);//清除屏幕顯示:數據指針清零,所有顯示清零;
DELAY_US(12000);//延遲200us
lcd_write_cmd(0x06);//設定輸入方式,增量不移位
DELAY_US(500);//延遲500us
}
void lcd_write_cmd(uchar cmd){
LCD_EN=0;
LCD_RS=0; //指令
//LCD_RW=0; //寫入
//起始位置爲0x80,對應GPIO0,若要在GPIO2上開始寫指令,需要將0x80左移兩位。
LCD_DB=(cmd<<2)|0x0000;//賦值給D0-D7對應的GPIO2-GPIO9引腳,0x0000對應EN和RS,因爲前面都是0,所以這邊寫成0就可以了
DELAY_US(500); //讓數據穩定下來
LCD_EN=1; //執行寫指令(寫入時序)
DELAY_US(1000); //保持時間
LCD_EN=0;
}
void lcd_write_dat(uchar dat){
LCD_EN=0;
LCD_RS=1; //數據
//LCD_RW=0; //寫入
LCD_DB=(dat<<2)|0x0001;//賦值給D0-D7對應的GPIO2-GPIO9引腳,0x0001對應 LCD_EN=0和LCD_RS=1;
DELAY_US(500);
LCD_EN=1; //允許
DELAY_US(1000);
LCD_EN=0;
}
void LCD12864SetAddress_f( uchar x, uchar y )
{
unsigned char byAddress;
switch( y )
{
case 0 :
byAddress = 0x80 + x;
break;
case 1 :
byAddress = 0x90 + x;
break;
case 2 :
byAddress = 0x88 + x;
break;
case 3 :
byAddress = 0x98 + x;
break;
default :
break;
}
lcd_write_cmd( byAddress ) ;
}
void show(uchar x,uchar y,uchar * data)
{
LCD12864SetAddress_f( x, y );
while (*data != '\0')
{
lcd_write_dat(*data);
data++; //地址 +1
DELAY_US(500); //延時500us
}
}
以上就是代碼的所有部分。首先說明一下,這些代碼完全可用,但是針對不同demo板,引腳配置上會不同,需要各位看原理圖後再確定。
另外,我在調試的時候也發現一個bug,就是ds18b20在初始化的時候,無論是否成功,都會跳出(當然最後就是return 0了),但是不影響顯示,我也就沒去解決這個bug。如果各位有興趣,可以在自己的板子上試試。
接下來也不知道什麼時候有空再玩玩dsp了,之後打算把上面採集到的溫度數據通過串口發送給pc,並用txt或excel保存起來。ti的ccs裏有graph模塊,但是隻能讓你看,卻無法將時間序列上的數據導出,這是一個缺點。在使用飛思卡爾的freeMaster的時候,這個軟件具有數據導出爲txt的功能,還是很不錯的,希望ti能實現。
tips:ccs裏tool---save memory只能保存memory中的數據,時間序列上的點無法導出。我看到的是這樣的,如果大家有其他更好的方法,希望各位可以提出,大家一起學習。