?? 23.c
字號:
#include <sst89E564RD.H>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define disdata P0 //顯示數據碼輸出口
#define channel_0 0x02 //單通道0輸入選擇
#define channel_1 0x03 //單通道1輸入選擇
sbit ADC_CS = P3^4; //片選端
sbit ADC_CLK= P1^0; //時鐘端
sbit ADC_DI = P1^1; //數據輸入輸出復用
sbit ADC_DO = P1^1; //DI和DO端都接在P1.1
sbit ACC0=ACC^0; //通道與輸入方式控制字
sbit ACC1=ACC^1; //通道與輸入方式控制字
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
uint data dis[4]={0x00,0x00,0x00,0x00};
//定義3個顯示數據單元和一個數據存儲單元
uchar code dis4[] = {"DIGITALVOLTMETER"};
uchar code dis5[] = {" VOLTAGE: . V "};
/********************************************************************/
/* */
/* 延時函數 */
/* */
/********************************************************************/
void delay(uchar ms)
{
while(ms--)
{
uchar i;
for(i=0;i<250;i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
/********************************************************************/
/* */
/*檢查LCD忙狀態 */
/*lcd_busy為1時,忙,等待。lcd-busy為0時,閑,可寫指令與數據。 */
/* */
/********************************************************************/
bit lcd_busy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
result = (bit)(P0&0x80);
LCD_EN = 0;
return result;
}
/********************************************************************/
/* */
/*寫指令數據到LCD */
/*RS=L,RW=L,E=高脈沖,D0-D7=指令碼。 */
/* */
/********************************************************************/
void lcd_wcmd(uchar cmd)
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 0;
}
/********************************************************************/
/* */
/*寫顯示數據到LCD */
/*RS=H,RW=L,E=高脈沖,D0-D7=數據。 */
/* */
/********************************************************************/
void lcd_wdat(uchar dat)
{
while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 0;
}
/********************************************************************/
/* */
/* LCD初始化設定 */
/* */
/********************************************************************/
void lcd_init()
{
lcd_wcmd(0x38); //16*2顯示,5*7點陣,8位數據
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x0c); //顯示開,關光標
delay(5);
lcd_wcmd(0x06); //移動光標
delay(5);
lcd_wcmd(0x01); //清除LCD的顯示內容
delay(5);
}
/********************************************************************/
/* */
/* 設定顯示位置 */
/* */
/********************************************************************/
void lcd_pos(uchar pos)
{
lcd_wcmd(pos | 0x80); //數據指針=80+地址變量
}
/********************************************************************/
/* */
/* 啟動ADC轉換 */
/* */
/********************************************************************/
void ADC_start()
{
ADC_CS=1; //一個轉換周期開始
_nop_();
ADC_CLK=0;
_nop_();
ADC_CS=0; //CS置0,片選有效
_nop_();
ADC_DI=1; //DI置1,起始位
_nop_();
ADC_CLK=1; //第一個脈沖
_nop_();
ADC_DI=0; //在負跳變之前加一個DI反轉操作
_nop_();
ADC_CLK=0;
_nop_();
}
/********************************************************************/
/* */
/*AD轉換函數 */
/*選擇輸入通道,輸入信號的模式《單端輸入,或差分輸入》 */
/*模數轉換 */
/* */
/********************************************************************/
int ADC_read(uchar mode)
{
uchar i;
ADC_start(); //啟動轉換開始
ACC=mode;
ADC_DI=ACC1; //輸出控制位1,DI=1,單通道輸入,DI=0,差分輸入。
ADC_CLK=1; //第二個脈沖
_nop_();
ADC_DI=0;
ADC_CLK=0;
_nop_();
ADC_DI=ACC0; //輸出控制位0,DI=0,通道0輸入,DI=1,通道1輸入。
ADC_CLK=1; //第三個脈沖
_nop_();
ADC_DI=1;
ADC_CLK=0; //輸入模式和通道號已經選擇完。
ADC_CLK=1; //第四個脈沖
ACC=0;
for(i=8;i>0;i--) //讀取8位數據
{
ADC_CLK=0; //脈沖下降沿
ACC=ACC<<1;
ACC0=ADC_DO; //讀取DO端數據
_nop_();
_nop_();
ADC_CLK=1;
}
ADC_CS=1; //CS=1,片選無效。
return(ACC);
}
/********************************************************************/
/* */
/* 數據處理與顯示 */
/* 將采集到的數據進行16進制轉換為ASCLL碼,并送顯示。 */
/* */
/********************************************************************/
show_value(uchar ad_data)
{
dis[2]=ad_data/51; //AD值轉換為3為BCD碼,最大為5.00V。
dis[2]=dis[2]+0x30;
dis[3]=ad_data%51; //余數暫存
dis[3]=dis[3]*10; //計算小數第一位
dis[1]=dis[3]/51;
dis[1]=dis[1]+0x30;
dis[3]=dis[3]%51;
dis[3]=dis[3]*10; //計算小數第二位
dis[0]=dis[3]/51; //
dis[0]=dis[0]+0x30;
lcd_pos(0x4a);
lcd_wdat(dis[2]); //整數位顯示
lcd_pos(0x4c);
lcd_wdat(dis[1]); //第一位小數顯示
lcd_pos(0x4d);
lcd_wdat(dis[0]); //第二位小數顯示
}
/********************************************************************/
/* */
/* 主程序 */
/* */
/********************************************************************/
void main()
{
uchar i,n;
delay(10); //延時
lcd_init(); //初始化LCD
lcd_pos(0); //設置顯示位置為第一行的第1個字符
i = 0;
while(dis4[i] != '\0')
{ //顯示字符"DIGITALVOLTMETER"
lcd_wdat(dis4[i]);
i++;
}
lcd_pos(0x40); //設置顯示位置為第二行第1個字符
i = 0;
while(dis5[i] != '\0')
{
lcd_wdat(dis5[i]); //顯示字符" VOLTAGE: . V "
i++;
}
while(1)
{
n=ADC_read(channel_0); //采集值送入n
show_value(n); //n中數據處理與顯示
delay(50); //延時50ms
}
}
/********************************************************************/
/* */
/*將n=ADC_read(channel_0)改為n=ADC_read(channel_1)即可使用JP6輸入 */
/* */
/********************************************************************/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -