久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標題:
c51單片機PCF8591 lcd1602做的電壓表顯示問題
[打印本頁]
作者:
kean
時間:
2018-12-17 16:16
標題:
c51單片機PCF8591 lcd1602做的電壓表顯示問題
整個流程為:mcu通過內部中斷PWM方式產生可調輸出電壓,接到PCF8591的AIN3,返回uchar類型,然后通過mcu顯示到lcd上。
現在問題是:不論我如何改變pwm的占空比,再或者不論PCF有沒有輸入都會輸出4.8。之前在考慮是不是i2c讀字節前需要空讀,但是沒有能夠寫出來,求助。
有思路的可以留言可以QQ聯系,謝謝。
[qq]1366970820[/qq]
只要能解決,500黑幣都給!
main.c
<div>#include <reg51.h> //51寄存器文件
#include <intrins.h>
#include <I2C.H>
#include"1602.h"
#define PCF8591 0x90 //PCF8591 地址</div><div>typedef unsigned int uint;//WORD代替unsigned int
typedef unsigned char uchar;
unsigned char timer0,timer1,second,second1;
unsigned int count,count1,mid;
unsigned int key;
unsigned char v,ss,aa;
unsigned long test_ss;
sbit PWM=P3^7;
unsigned int i,j;
unsigned char Data,keyFlag;
uint a,b,c;
uchar shi,ge,ms,vt;
uint a,b,c,o;
float why;</div><div>void scan_key();
int T1s();</div><div>uchar dis1[] = {"V1:"};
uchar dis2[] = {"V2:"};
uchar dis1t[] = {"T1:"};
uchar dis2t[] = {"T2:"};
uchar dist1[] = "00.0s";
uchar dist2[] = "00.0x";</div><div>void system_Ini()
{
TMOD = 0x11;
//PWM
TH0 = 0xff;
TL0 = 0xf7;
TH1 = 0xff;
TL1 = 0xf7;
EA = 1;
ET0 = 1;
ET1 = 1;
TR0 = 1;
TR1 = 1;
//IE =0x8A;
}
/*******************************************************************
ADC發送字節[命令]數據函數
*******************************************************************/
bit ISendByte(unsigned char sla,unsigned char c)
{
Start_I2c(); //啟動總線
SendByte(sla); //發送器件地址
if(ack==0)return(0);
SendByte(c); //發送數據
if(ack==0)return(0);
Stop_I2c(); //結束總線
return(1);
}
/*******************************************************************
ADC讀字節數據函數
*******************************************************************/
unsigned char IRcvByte(unsigned char sla)
{ unsigned char c = 0;
Start_I2c(); //啟動總線
SendByte(sla+1); //發送器件地址
if(ack==0)return(0);
c=RcvByte(); //讀取第1路電壓值,范圍是0-255
c=0;
c=RcvByte(); //讀取第1路電壓值,范圍是0-255
//for(what=0;what<5;what++)//連續讀5次,取最后一次,以便讀取穩定值
Ack_I2c(1); //發送非就答位
Stop_I2c(); //結束總線
return(c);
}
main()
{
BYTE i;
//uchar shi,ge;
lcd_init(); //初始化LCD
system_Ini();
delay(10);
lcd_pos(0); //設置顯示位置為第一行的第1個字符
i = 0;
while(dis1[i] != '\0')
{ //顯示字符"一號電壓"
lcd_wdat(dis1[i]);
i++;
}
lcd_pos(8); //設置顯示位置為第一行的第9個字符
i = 0;
while(dis1[i] != '\0')
{ //顯示字符"一號時間"
lcd_wdat(dis1t[i]);
i++;
}
lcd_pos(0x40); //設置顯示位置為第二行第1個字符
i = 0;
while(dis2[i] != '\0')
{
lcd_wdat(dis2[i]); //顯示字符"二號電壓"
i++;
}
lcd_pos(0x48); //設置顯示位置為第二行第9個字符
i = 0;
while(dis2[i] != '\0')
{
lcd_wdat(dis2t[i]); //顯示字符"二號時間"
i++;
}
lcd_pos(0x4b); //設置顯示位置為第一行的第12個字符
lcd_wdat(0x30+0);
lcd_pos(0x4c); //設置顯示位置為第一行的第12個字符
lcd_wdat(0x30+0);
lcd_pos(0x4d); //設置顯示位置為第一行的第12個字符
lcd_wdat('.');
lcd_pos(0x4e); //設置顯示位置為第一行的第12個字符
lcd_wdat(0x30+0);
//while(1);
lcd_pos(3); //設置顯示位置為第一行的第12個字符
lcd_wdat(0x30+0);
lcd_pos(4); //設置顯示位置為第一行的第12個字符
lcd_wdat('.');
lcd_pos(5); //設置顯示位置為第一行的第12個字符
lcd_wdat(0x30+0);
while(1)
{
//if(ms>0) ISendByte(PCF8591,0x43);
if((count>0)&&(keyFlag == 1))
{
ISendByte(PCF8591,0x43);
Data=IRcvByte(PCF8591);
ss=Data*48/255;
a = ss/10 ;
b = (ss)%10;
//c = (ss-a*100-b*10)%10;
lcd_pos(3); //設置顯示位置為第一行的第12個字符
lcd_wdat('0'+a);
lcd_pos(4); //設置顯示位置為第一行的第12個字符
lcd_wdat('.');
lcd_pos(5); //設置顯示位置為第一行的第12個字符
lcd_wdat(0x30+b);
//lcd_pos(6); //設置顯示位置為第一行的第12個字符
//lcd_wdat(0x30+c);
shi=second/10;
ge=second%10;
lcd_pos(0x4b); //設置顯示位置為第2行的第12個字符
lcd_wdat(0x30+shi);
lcd_pos(0x4c); //設置顯示位置為第2行的第12個字符
lcd_wdat(0x30+ge);
lcd_pos(0x4d); //設置顯示位置為第2行的第12個字符
lcd_wdat('.');
lcd_pos(0x4e); //設置顯示位置為第2行的第12個字符
lcd_wdat(0x30+ms);
}
}
}
/*************************************
[ t1 (0.5ms)中斷] 中斷中做 PWM 輸出
------------1000/(0.02ms*250)=200Hz
*************************************/
void T0zd(void) interrupt 1 //3 為定時器1的中斷號 1 定時器0的中斷號 0 外部中斷1 2 外部中斷2 4 串口中斷
{
scan_key(); //檢測按鍵
switch(key){
case 8:
{
keyFlag = 1;
TR0 = 0;
TH0 = 0xff;
TL0 = 0xf7;
TR0 = 1;
timer1++;
if(timer1>=100)
{
timer1=0;
ms++;
vt++;
}
if(timer1<=0) PWM=1;
else PWM=0;
if(ms == 10)
{
ms = 0;
count++;
if(count == 10)
{
count = 0;
second++;
if(second == 60)
{
second = 0;
}
}}
else
{
}
}break;
default:;
}
}
void T1zd(void) interrupt 3 //3 為定時器1的中斷號 1 定時器0的中斷號 0 外部中斷1 2 外部中斷2 4 串口中斷
{
}
void scan_key() //按鍵檢測函數
{
if(P1== 0xfe)
key= 1;
if(P1== 0xfd)
key= 2;
if(P1== 0xfb)
key= 3;
if(P1== 0xf7)
key= 4;
if(P1== 0xef)
key= 5;
if(P1== 0xdf)
key= 6;
if(P1== 0xbf)
key= 7;
if(P1== 0x7f)
key= 8;
}
</div>
復制代碼
I2C.c
<div><font size="2">
/*************************此部分為I2C總線的驅動程序*************************************/
#include<reg52.h>
#include <intrins.h>
#include <I2C.H>
#define NOP() _nop_() /* 定義空指令 */
#define _Nop() _nop_() /*定義空指令*/
sbit SCL=P2^1; //I2C 時鐘
sbit SDA=P2^0; //I2C 數據
bit ack; /*應答標志位*/
/*******************************************************************
起動總線函數
函數原型: void Start_I2c();
功能: 啟動I2C總線,即發送I2C起始條件.
********************************************************************/
void Start_I2c()
{
SDA=1; /*發送起始條件的數據信號*/
_Nop();
SCL=1;
_Nop(); /*起始條件建立時間大于4.7us,延時*/
_Nop();
_Nop();
_Nop();
_Nop();
SDA=0; /*發送起始信號*/
_Nop(); /* 起始條件鎖定時間大于4μs*/
_Nop();
_Nop();
_Nop();
_Nop();
SCL=0; /*鉗住I2C總線,準備發送或接收數據 */
_Nop();
_Nop();
}
/*******************************************************************
結束總線函數
函數原型: void Stop_I2c();
功能: 結束I2C總線,即發送I2C結束條件.
********************************************************************/
void Stop_I2c()
{
SDA=0; /*發送結束條件的數據信號*/
_Nop(); /*發送結束條件的時鐘信號*/
SCL=1; /*結束條件建立時間大于4μs*/
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SDA=1; /*發送I2C總線結束信號*/
_Nop();
_Nop();
_Nop();
_Nop();
}
/*******************************************************************
字節數據發送函數
函數原型: void SendByte(UCHAR c);
功能: 將數據c發送出去,可以是地址,也可以是數據,發完后等待應答,并對
此狀態位進行操作.(不應答或非應答都使ack=0)
發送數據正常,ack=1; ack=0表示被控器無應答或損壞。
********************************************************************/
void SendByte(unsigned char c)
{
unsigned char BitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++) /*要傳送的數據長度為8位*/
{
if((c<<BitCnt)&0x80)SDA=1; /*判斷發送位*/
else SDA=0;
_Nop();
SCL=1; /*置時鐘線為高,通知被控器開始接收數據位*/
_Nop();
_Nop(); /*保證時鐘高電平周期大于4μs*/
_Nop();
_Nop();
_Nop();
SCL=0;
}
_Nop();
_Nop();
SDA=1; /*8位發送完后釋放數據線,準備接收應答位*/
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop();
_Nop();
if(SDA==1)ack=0;
else ack=1; /*判斷是否接收到應答信號*/
SCL=0;
_Nop();
_Nop();
}
/*******************************************************************
字節數據接收函數
函數原型: UCHAR RcvByte();
功能: 用來接收從器件傳來的數據,并判斷總線錯誤(不發應答信號),
發完后請用應答函數應答從機。
********************************************************************/
unsigned char RcvByte()
{
unsigned char retc;
unsigned char BitCnt;
retc=0;
SDA=1; /*置數據線為輸入方式*/
for(BitCnt=0;BitCnt<8;BitCnt++)
{
_Nop();
SCL=0; /*置時鐘線為低,準備接收數據位*/
_Nop();
_Nop(); /*時鐘低電平周期大于4.7μs*/
_Nop();
_Nop();
_Nop();
SCL=1; /*置時鐘線為高使數據線上數據有效*/
_Nop();
_Nop();
retc=retc<<1;
if(SDA==1)retc=retc+1; /*讀數據位,接收的數據位放入retc中 */
_Nop();
_Nop();
}
SCL=0;
_Nop();
_Nop();
return(retc);
}
/********************************************************************
應答子函數
函數原型: void Ack_I2c(bit a);
功能: 主控器進行應答信號(可以是應答或非應答信號,由位參數a決定)
********************************************************************/
void Ack_I2c(bit a)
{
if(a==0)SDA=0; /*在此發出應答或非應答信號 */
else SDA=1;
_Nop();
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop(); /*時鐘低電平周期大于4μs*/
_Nop();
_Nop();
_Nop();
SCL=0; /*清時鐘線,鉗住I2C總線以便繼續接收*/
_Nop();
_Nop();
}</font>
</div>
復制代碼
作者:
kean
時間:
2018-12-17 16:30
補充一點:PWM輸出的電壓值通過電壓表測過啦,是沒有問題的。
歡迎光臨 (http://m.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
亚洲淫视频
|
亚洲日本欧美日韩高观看
|
亚洲一区二区三区免费在线观看
|
亚洲精品大片
|
亚洲 中文 欧美 日韩 在线观看
|
色毛片
|
免费一级淫片aaa片毛片a级
|
亚洲精品乱码久久久久v最新版
|
国产日韩欧美另类
|
亚洲精品日本
|
国产福利一区二区
|
国产精品一区二区欧美
|
激情a
|
天堂在线91
|
黑人精品欧美一区二区蜜桃
|
九一精品
|
久久一本
|
欧美八区
|
99久久精品国产一区二区三区
|
美女视频久久
|
玖玖久久
|
男人的天堂视频网站
|
精品一区二区三区四区
|
国产一区二区三区视频
|
国产精品久久久久影院色老大
|
午夜视频网站
|
日本特黄a级高清免费大片 成年人黄色小视频
|
欧美日韩在线综合
|
亚洲一区二区三区欧美
|
久久中文免费视频
|
国产伦精品一区二区三区精品视频
|
成人久久
|
成人性生交大片免费看中文带字幕
|
激情伊人网
|
91亚洲精品国偷拍自产在线观看
|
色网在线观看
|
成人三级视频
|
夫妻午夜影院
|
国产日产精品一区二区三区四区
|
97精品超碰一区二区三区
|
国产免费国产
|