Ⅰ 【求助】STC12C5A60S系列單片機,實現AD采樣並用數碼管顯示,利用AD采樣得到的值控制輸出占空比可調的PWM
#include<reg52.h>
#include <I2C.H>
#define PCF8591 0x90 //PCF8591 地址
//else IO
sbit LS138A=P2^2;
sbit LS138B=P2^3;
sbit LS138C=P2^4;
//此表為 LED 的字模, 共陰數碼管 0-9 -
unsigned char code Disp_Tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char AD_CHANNEL;
unsigned long xdata LedOut[8];
unsigned int D[32];
/*******************************************************************
DAC 變換, 轉化函數
*******************************************************************/
bit DACconversion(unsigned char sla,unsigned char c, unsigned char Val)
{
Start_I2c(); //啟動匯流排
SendByte(sla); //發送器件地址
if(ack==0)return(0);
SendByte(c); //發送控制位元組
if(ack==0)return(0);
SendByte(Val); //發送DAC的數值
if(ack==0)return(0);
Stop_I2c(); //結束匯流排
return(1);
}
/*******************************************************************
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;
Start_I2c(); //啟動匯流排
SendByte(sla+1); //發送器件地址
if(ack==0)return(0);
c=RcvByte(); //讀取數據0
Ack_I2c(1); //發送非就答位
Stop_I2c(); //結束匯流排
return(c);
}
//******************************************************************/
main()
{ char i,j;
while(1)
{/********以下AD-DA處理*************/
switch(AD_CHANNEL)
{
case 0: ISendByte(PCF8591,0x41);
D[0]=IRcvByte(PCF8591)*2; //ADC0 模數轉換1 放大2倍顯示
break;
case 1: ISendByte(PCF8591,0x42);
D[1]=IRcvByte(PCF8591)*2; //ADC1 模數轉換2
break;
case 2: ISendByte(PCF8591,0x43);
D[2]=IRcvByte(PCF8591)*2; //ADC2模數轉換3
break;
case 3: ISendByte(PCF8591,0x40);
D[3]=IRcvByte(PCF8591)*2; //ADC3 模數轉換4
break;
case 4: DACconversion(PCF8591,0x40, D[4]/4); //DAC 數模轉換
break;
}
// D[4]=400; //數字--->>模擬輸出
D[4]=D[0]; // 把模擬輸入 采樣的信號 通過數模轉換輸出
if(++AD_CHANNEL>4) AD_CHANNEL=0;
/********以下將AD的值送到LED數碼管顯示*************/
LedOut[0]=Disp_Tab[D[1]%10000/1000];
LedOut[1]=Disp_Tab[D[1]%1000/100];
LedOut[2]=Disp_Tab[D[1]%100/10]|0x80;
LedOut[3]=Disp_Tab[D[1]%10];
LedOut[4]=Disp_Tab[D[0]%10000/1000];
LedOut[5]=Disp_Tab[D[0]%1000/100];
LedOut[6]=Disp_Tab[D[0]%100/10]|0x80;
LedOut[7]=Disp_Tab[D[0]%10];
for( i=0; i<8; i++)
{P0 = LedOut[i];
switch(i) //使用switch 語句控制138解碼器 也可以是用查表的方式 學員可以試著自己修改
{
case 0:LS138A=0; LS138B=0; LS138C=0; break;
case 1:LS138A=1; LS138B=0; LS138C=0; break;
case 2:LS138A=0; LS138B=1; LS138C=0; break;
case 3:LS138A=1; LS138B=1; LS138C=0; break;
case 4:LS138A=0; LS138B=0; LS138C=1; break;
case 5:LS138A=1; LS138B=0; LS138C=1; break;
case 6:LS138A=0; LS138B=1; LS138C=1; break;
case 7:LS138A=1; LS138B=1; LS138C=1; break;
}
for (j = 0 ; j<90 ;j++) { ;} //掃描間隔時間
}
P0 = 0;
}
}
Ⅱ 基於STC89C52單片機的電子時鍾系統的設計
就弄個AT24C02讀寫程序,注釋詳細看這個也應該用不到專門的時鍾晶元,思路:開機進入主循環之前讀取晶元中的數據,設置個標志位沒30秒取反一次。或者但秒=0或為60時取反一次也是半分種吸和或斷開,利用單片機本身的定時器,例如每個50ms中斷一次20次就是一秒,bit ack; //應答標志位sbit SDA=P2^1;
sbit SCL=P2^0;/*------------------------------------------------
啟動匯流排
------------------------------------------------*/
void Start_I2c()
{
SDA=1; //發送起始條件的數據信號
_Nop();
SCL=1;
_Nop(); //起始條件建立時間大於4.7us,延時
_Nop();
_Nop();
_Nop();
_Nop();
SDA=0; //發送起始信號
_Nop(); //起始條件鎖定時間大於4μ
_Nop();
_Nop();
_Nop();
_Nop();
SCL=0; //鉗住I2C匯流排,准備發送或接收數據
_Nop();
_Nop();
}
/*------------------------------------------------
結束匯流排
------------------------------------------------*/
void Stop_I2c()
{
SDA=0; //發送結束條件的數據信號
_Nop(); //發送結束條件的時鍾信號
SCL=1; //結束條件建立時間大於4μ
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SDA=1; //發送I2C匯流排結束信號
_Nop();
_Nop();
_Nop();
_Nop();
}
/*----------------------------------------------------------------
位元組數據傳送函數
函數原型: void SendByte(unsigned char 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μ
_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();
} /*----------------------------------------------------------------
位元組數據傳送函數
函數原型: unsigned char 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.7us
_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(void);
----------------------------------------------------------------*/
void Ack_I2c(void)
{
SDA=0;
_Nop();
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop(); //時鍾低電平周期大於4μ
_Nop();
_Nop();
_Nop();
SCL=0; //清時鍾線,鉗住I2C匯流排以便繼續接收
_Nop();
_Nop();
}/*----------------------------------------------------------------
向有子地址器件發送多位元組數據函數
函數原型: bit ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no);
功能: 從啟動匯流排到發送地址,子地址,數據,結束匯流排的全過程,從器件
地址sla,子地址suba,發送內容是s指向的內容,發送no個位元組。
如果返回1表示操作成功,否則操作有誤。
注意: 使用前必須已結束匯流排。
----------------------------------------------------------------*/
bit ISendStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)
{
unsigned char i;
for(i=0;i<no;i++)
{
Start_I2c(); //啟動匯流排
SendByte(sla); //發送器件地址
if(ack==0)return(0);
SendByte(suba); //發送器件子地址
if(ack==0)return(0);
SendByte(*s); //發送數據
if(ack==0)return(0);
Stop_I2c(); //結束匯流排
DelayMs(1); //必須延時等待晶元內部自動處理數據完畢
s++;
suba++;
}
return(1);
}/*----------------------------------------------------------------
向無子地址器件讀位元組數據函數
函數原型: bit IRcvByte(unsigned char sla,ucahr *c);
功能: 從啟動匯流排到發送地址,讀數據,結束匯流排的全過程,從器件地
址sla,返回值在c.
如果返回1表示操作成功,否則操作有誤。
注意: 使用前必須已結束匯流排。
----------------------------------------------------------------*/
/*bit IRcvByte(unsigned char sla,unsigned char *c)
{
Start_I2c(); //啟動匯流排
SendByte(sla+1); //發送器件地址
if(ack==0)return(0);
*c=RcvByte(); //讀取數據
NoAck_I2c(); //發送非就答位
Stop_I2c(); //結束匯流排
return(1);
}*/
/*----------------------------------------------------------------
向有子地址器件讀取多位元組數據函數
函數原型: bit ISendStr(unsigned char sla,unsigned char suba,ucahr *s,unsigned char no);
功能: 從啟動匯流排到發送地址,子地址,讀數據,結束匯流排的全過程,從器件
地址sla,子地址suba,讀出的內容放入s指向的存儲區,讀no個位元組。
如果返回1表示操作成功,否則操作有誤。
注意: 使用前必須已結束匯流排。
----------------------------------------------------------------*/
bit IRcvStr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char no)
{
unsigned char i; Start_I2c(); //啟動匯流排
SendByte(sla); //發送器件地址
if(ack==0)return(0);
SendByte(suba); //發送器件子地址
if(ack==0)return(0); Start_I2c();
SendByte(sla+1);
if(ack==0)return(0); for(i=0;i<no-1;i++)
{
*s=RcvByte(); //發送數據
Ack_I2c(); //發送就答位
s++;
}
*s=RcvByte();
NoAck_I2c(); //發送非應位
Stop_I2c(); //結束匯流排
return(1);
}
Ⅲ 請問AVRmega16單片機上面的IIC匯流排提到的SLA+R/W是指的是什麼啊
SLA+R/W 共八位
SLA:前七位,表示從機地址(所以最多支持128個從設備)
R/W:最後一位,為READ/WRITE控制位;如果READ/WRITE 為1,則執行讀操作;否則執行寫操作。
Ⅳ 具體怎麼樣用單片機控制步進電機的轉速
也許不是程序的問題,而是電機轉動慣量大,當驅動時間小於某一數值,則不能完成一個步進。表現為卡住。
能把電機轉的更快的出路:
1.從程序上:起動時轉速是逐步加速,停止時轉速是逐步減速,即不要從靜止一下子加到2.2ms。
2.從機械上,電機與被驅動物之間加彈性聯接,得以緩沖。
3.從電氣驅動上,採用雙電壓驅動,以加快驅動(激磁)電流的建立。
Ⅳ 單片機i2c匯流排編程,
return 一旦執行,就退出函數了。
也就是說 如果flag==0 那麼就return0 後面的就不執行了,退出函數
Ⅵ 關於51單片機的小問題
運用IIC匯流排和串口通信 ,給你兩個例子參考
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define AddWr 0xa0 //器件地址選擇及寫標志
#define AddRd 0xa1 //器件地址選擇及讀標志
/*有關全局變數*/
sbit Sda= P3^7; //串列數據
sbit Scl= P3^6; //串列時鍾
sbit WP= P3^5; //硬體防寫
uchar outdata[4]; //定義發送的位元組數
uchar indata[4];
uchar count, count_r=0;
SendData(uchar *a)
{
outdata[0] = a[0];
outdata[1] = a[1];
outdata[2] = a[2];
outdata[3] = a[3];
count = 1;
SBUF=outdata[0];
}
void mDelay(uchar j)
{
uchar i;
for(;j>0;j--)
for(i=0;i<125;i--);
}
/*起始*/
void Start(void)
{
Sda=1;
Scl=1;
_nop_();_nop_();_nop_();_nop_();
Sda=0;
_nop_();_nop_();_nop_();_nop_();
}
/*停止*/
void Stop(void)
{
Sda=0;
Scl=1;
_nop_();_nop_();_nop_();_nop_();
Sda=1;
_nop_();_nop_();_nop_();_nop_();
}
/*應答*/
void Ack(void)
{
Sda=0;
_nop_();_nop_();_nop_();_nop_();
Scl=1;
_nop_();_nop_();_nop_();_nop_();
Scl=0;
}
/*反向應答位*/
void NoAck(void)
{
Sda=1;
_nop_();_nop_();_nop_();_nop_();
Scl=1;
_nop_();_nop_();_nop_();_nop_();
Scl=0;
}
/*發送數據子程序,Data為要求發送的數據*/
void Send(uchar Data)
{
uchar BitCounter=8; //位數控制
uchar temp; //中間變數控制
do
{
temp=Data;
Scl=0;
_nop_();_nop_();_nop_();_nop_();
if((temp&0x80)==0x80) //如果最高位是1
Sda=1;
else
Sda=0;
Scl=1;
temp=Data<<1; //RLC
Data=temp;
BitCounter--;
}while(BitCounter);
Scl=0;
}
/*讀一個位元組的數據,並返回該位元組值*/
uchar Read(void)
{
uchar temp=0;
uchar temp1=0;
uchar BitCounter=8;
Sda=1;
do{
Scl=0;
_nop_();_nop_();_nop_();_nop_();
Scl=1;
_nop_();_nop_();_nop_();_nop_();
if(Sda) //如果Sda=1
temp=temp|0x01; //temp的最低位置1
else
temp=temp&0xfe; //否則temp的最低位清0
if(BitCounter-1)
{
temp1=temp<<1;
temp=temp1;
}
BitCounter--;
}while(BitCounter);
return(temp);
}
//寫入多個位元組。
void WrToROMs(uchar *iData,uchar Address,uchar Num)
{
uchar i;
Start(); //發送啟動信號
Send(0xa0); //發送SLA+W
Ack();
Send(Address); //發送地址
Ack();
for(i=0;i<Num;i++)
{
Send(iData[i]);
Ack();
}
Stop();
mDelay(4); //延時4ms。。。。
}
void RdFromROM(uchar Data[],uchar Address,uchar Num)
{
uchar i;
uchar *PData;
PData=Data;
for(i=0;i<Num;i++)
{
Start();
Send(0xa0);
Ack();
Send(Address+i);
Ack();
Start();
Send(0xa1);
Ack();
*(PData+i)=Read();
Scl=0;
NoAck();
Stop();
}
}
void main()
{
uchar Number[4]={1,2,3,4};
/* 系統初始化 */
TMOD = 0x20; //定時器T1使用工作方式2
TH1 = 253; // 設置初值
TL1 = 253;
TR1 = 1; // 開始計時
SCON = 0x50; //工作方式1,波特率9600bps,允許接收
ES = 1;
EA = 1; // 打開所有中斷
TI = 0;
RI = 0;
WP= 1;
WrToROMs(Number,4,4); //將初始化後的數值寫入EEPROM
mDelay(20);
Number[0]=0;
Number[1]=0;
Number[2]=0;
Number[3]=0; //將數組中的值清掉,以驗證讀出的數是否正確
RdFromROM(Number,4,4);
SendData(Number) ; //發送到串口。
while(1);
}
void RSINTR() interrupt 4 using 2
{
uchar InPut3;
if(TI==1)
{
TI=0;
if(count!=4)
{
SBUF= outdata[count];
count++;
}
}
if(RI==1)
{
InPut3=SBUF;
if(InPut3==90) //判斷起始位
count_r=0;
indata[count_r]=InPut3;
count_r++;
RI=0;
if (count_r==4)
{
//數據接收完畢處理。
}
}
}
---------------------------------------------------------------------
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar outdata[5]; //定義發送的位元組數
uchar indata[4];
uchar count, count_r=0;
SendData(uchar *a)
{
outdata[0] = a[0];
outdata[1] = a[1];
outdata[2] = a[2];
outdata[3] = a[3];
outdata[4] = a[4];
count = 1;
SBUF=outdata[0];
}
void main()
{
uchar str[6]={""};
/* 系統初始化 */
TMOD = 0x20; //定時器T1使用工作方式2
TH1 = 253; // 設置初值
TL1 = 253;
TR1 = 1; // 開始計時
SCON = 0x50; //工作方式1,波特率9600bps,允許接收
ES = 1;
EA = 1; // 打開所以中斷
TI = 0;
RI = 0;
SendData(str) ; //發送到串口。
while(1);
}
void RSINTR() interrupt 4 using 2
{
uchar InPut3;
if(TI==1) //發送中斷
{
TI=0;
if(count!=5) //發送完5位數據
{
SBUF= outdata[count];
count++;
}
}
if(RI==1) //接收中斷
{
InPut3=SBUF;
indata[count_r]=InPut3;
count_r++;
RI=0;
if (count_r==4)//接收完4位數據
{
//數據接收完畢處理。
count_r=0;
P0 = indata[3];
}
}
}
Ⅶ 51單片機如何模擬I2C匯流排中從機接收ID,發送數據的程序
#include /*頭文件的包含*/
#include
#define uchar unsigned char /*宏定義*/
#define uint unsigned int
/*埠位定義*/
sbit BELL_OUT=P3^5;
sbit SCL="P1"^3;/*模擬I2C數據傳送位*/
sbit SDA="P1"^4;/*模擬I2C時鍾控制位*/
bit ack; /*應答標志位*/
/*********************************************************************
起動匯流排函數
函數原型: void Start_I2c();
功能:啟動I2C匯流排,即發送I2C起始條件
********************************************************************/
void Start_I2c()
{
SDA="1"; /*發送起始條件的數據信號*/
_nop_();
SCL="1"; /*起始條件建立時間大於4.7us,延時*/
_nop_();
SDA="0"; /*發送起始信號*/
_nop_(); /* 起始條件鎖定時間大於4μs*/
SCL="0"; /*鉗住I2C匯流排,准備發送或接收數據 */
_nop_();
}
/***********************************************
結束匯流排函數
函數原型: void Stop_I2c();
功能:結束I2C匯流排,即發送I2C結束條件
***********************************************/
void Stop_I2c()
{
SDA="0"; /*發送結束條件的數據信號*/
_nop_(); /*發送結束條件的時鍾信號*/
SCL="1"; /*結束條件建立時間大於4μs*/
_nop_();
SDA="1"; /*發送I2C匯流排結束信號*/
_nop_();
}
/*******************************************************************
位元組數據傳送函數
函數原型: void SendByte(uchar c);
功能:將數據c發送出去,可以是地址,也可以是數據,發完後等待應答,並對此狀
態位進行操作(不應答或非應答都使ack=0 假) 。發送數據正常,ack=1;
ack=0表示被控器無應答或損壞。
********************************************************************/
void SendByte(uchar c)
{
uchar BitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++) /*要傳送的數據長度為8位*/
{
SCL="0";
if((c<
else SDA="0";
SCL="1"; /*置時鍾線為高,通知被控器開始接收數據位*/
_nop_(); /*保證時鍾高電平周期大於4μs*/
}
//從機應答,可以用應答和非應答信號代替
_nop_();
SCL="0";
_nop_();
SDA="1"; //
_nop_();
SCL="1";
_nop_();
if(SDA==1){ack=0;} /*判斷是否接收到應答信號*/
else ack="1";
SCL="0";
_nop_();
}
/*******************************************************************
位元組數據傳送函數
函數原型: uchar RcvByte();
功能:用來接收從器件傳來的數據,並判斷匯流排錯誤(不發應答信號),
發完後請用應答函數。
********************************************************************/
uchar RcvByte()
{
uchar retc;
uchar BitCnt;
retc="0";
for(BitCnt=0;BitCnt<8;BitCnt++)
{
SCL="1"; /*置時鍾線為高使數據線上數據有效*/
_nop_();
retc="retc"<<1;
if(SDA==1) retc="retc"+1; /*讀數據位,接收的數據位放入retc中 */
SCL="0";
}
return(retc);
}
/********************************************************************
應答子函數
原型: void Ack_I2c();
功能:主控器進行應答信號
********************************************************************/
void Ack_I2c()
{
SDA="0"; /*在此發出應答信號 */
_nop_();
SCL="0";
_nop_();
SCL="1";
_nop_();
SCL="0"; /*清時鍾線,鉗住I2C匯流排以便繼續接收*/
_nop_();
SDA="1";
_nop_();
}
/********************************************************************
非應答子函數
原型: void NoAck_I2c();
功能:主控器進行非應答信號
********************************************************************/
void NoAck_I2c()
{
SDA="1"; /*在此發出非應答信號 */
_nop_();
SCL="1";
_nop_();
SCL="0"; /*清時鍾線,鉗住I2C匯流排以便繼續接收*/
}
/*******************************************************************
向無子地址器件發送位元組數據函數
函數原型: bit ISendByte(uchar sla,ucahr c);
功能:從啟動匯流排到發送地址,數據,結束匯流排的全過程,從器件地址sla。如果
返回1表示操作成功,否則操作有誤。
********************************************************************/
bit ISendByte(uchar sla,uchar c)
{
Start_I2c(); /*啟動匯流排*/
SendByte(sla); /*發送器件地址*/
if(ack==0)return(0);
SendByte(c); /*發送數據*/
if(ack==0)return(0);
Stop_I2c(); /*結束匯流排*/
return(1);
}
/*******************************************************************
向有子地址器件發送多位元組數據函數
函數原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能:從啟動匯流排到發送地址,子地址,數據,結束匯流排的全過程,從器件地址sla,
子地址suba,發送內容是s指向的內容,發送no個位元組。如果返回1表示
操作成功,否則操作有誤。
********************************************************************/
bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
{
uchar i;
Start_I2c(); /*啟動匯流排*/
SendByte(sla); /*發送器件地址*/
if(ack==0)return(0);
SendByte(suba); /*發送器件子地址*/
if(ack==0)return(0);
for(i=0;i
{
SendByte(*s); /*發送數據*/
if(ack==0)return(0);
s++;
}
Stop_I2c(); /*結束匯流排*/
//delayMs(1); //
return(1);
}
/*******************************************************************
向無子地址器件讀位元組數據函數
函數原型: bit IRcvByte(uchar sla,ucahr *c);
功能:從啟動匯流排到發送地址,讀數據,結束匯流排的全過程,從器件地址sla,返
回值在c。如果返回1表示操作成功,否則操作有誤。
********************************************************************/
bit IRcvByte(uchar sla,uchar *c)
{
Start_I2c(); /*啟動匯流排*/
SendByte(sla+1); /*發送器件地址*/
if(ack==0)return(0);
*c=RcvByte(); /*讀取數據*/
NoAck_I2c(); /*發送非就答位*/
Stop_I2c(); /*結束匯流排*/
return(1);
}
/**********************************************************************
向有子地址器件讀取多位元組數據函數
函數原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能:從啟動匯流排到發送地址,子地址,讀數據,結束匯流排的全過程,從器件地址sla,
子地址suba,讀出的內容放入s指向的存儲區,讀no個位元組。如果返回1
表示操作成功,否則操作有誤。
**********************************************************************/
bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
{
Start_I2c(); /*啟動匯流排*/
SendByte(sla); /*發送器件地址*/
if(ack==0)return(0);
SendByte(suba); /*發送器件子地址*/
if(ack==0)return(0);
Start_I2c();
SendByte(sla+1);
if(ack==0)return(0);
while(no!=1)
{
*s=RcvByte();/*發送數據*/
Ack_I2c(); /*發送就答位*/
s++;
no--;
}
*s=RcvByte();
NoAck_I2c(); /*發送非應位*/
Stop_I2c(); /*結束匯流排*/
return(1);
}
Ⅷ 51單片機通過三極體 驅動繼電器加熱 2000w的電熱絲接220V 選用什麼型號的繼電器給個電路圖及詳細解釋
SLA-12VDC-SL-A繼電器(30A) 5腳30A的繼電器 價格便宜 三塊錢上下 三極體 用SS8050或SS8550吧 或者組成達林頓管用 9012的電流太小 不推薦(驅動繼電器別忘了加續流二極體)
Ⅸ 單片機中 IRcvStr()是做什麼的
太神奇了,你就截了這樣一段,誰知道這是干什麼用的,
這里開了定時器中斷,你看中斷服務函數裡面是什麼內容就知道是做什麼用了;
IRcvStr,是IIC頭文件里的一個子函數,你搜一下就可以找到
向有子地址器件讀取多位元組數據函數
函數原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能: 從啟動匯流排到發送地址,子地址,讀數據,結束匯流排的全過程,從器件
地址sla,子地址suba,讀出的內容放入s指向的存儲區,讀no個位元組。
如果返回1表示操作成功,否則操作有誤。
注意: 使用前必須已結束匯流排。
bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
在下面的頭文件里也可以找到;
即使前面有這樣的定義,也要有這個函數的原型,或許在本身C文件里,或者在前麵包含的頭文件里,如#include"",#include<>
I2C的頭文件
===================================================
bit ack; /*應答標志位*/
/*定義空指令*/
void _Nop(){
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
/*******************************************************************
起動匯流排函數
函數原型: 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(uchar c){
uchar 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();
功能: 用來接收從器件傳來的數據,並判斷匯流排錯誤(不發應答信號),
發完後請用應答函數。
********************************************************************/
uchar RcvByte()
{
uchar retc;
uchar 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);
功能:主控器進行應答信號,(可以是應答或非應答信號)
********************************************************************/
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();
}
/*******************************************************************
向有子地址器件發送多位元組數據函數
函數原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能: 從啟動匯流排到發送地址,子地址,數據,結束匯流排的全過程,從器件
地址sla,子地址suba,發送內容是s指向的內容,發送no個位元組。
如果返回1表示操作成功,否則操作有誤。
注意: 使用前必須已結束匯流排。
********************************************************************/
bit ISendStr(uchar sla,uchar suba, uchar *s,uchar no)
{
uchar i, *tmp;
tmp=&i;
Start_I2c(); //啟動匯流排
SendByte(sla); //發送器件地址
if(ack==0)return(0);
SendByte(suba); //發送器件子地址
if(ack==0)return(0);
for(i=0;i <no;i++)
{
SendByte(*s); //發送數據
if(ack==0)return(0);
s++;
}
Stop_I2c(); //結束匯流排
return(1);
}
/*******************************************************************
向有子地址器件讀取多位元組數據函數
函數原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功能: 從啟動匯流排到發送地址,子地址,讀數據,結束匯流排的全過程,從器件
地址sla,子地址suba,讀出的內容放入s指向的存儲區,讀no個位元組。
如果返回1表示操作成功,否則操作有誤。
注意: 使用前必須已結束匯流排。
********************************************************************/
bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
{
uchar i;
Start_I2c(); /*啟動匯流排*/
SendByte(sla); /*發送器件地址*/
if(ack==0)return(0);
SendByte(suba); /*發送器件子地址*/
if(ack==0)return(0);
Start_I2c();
SendByte(sla+1);
if(ack==0)return(0);
for(i=0;i <no-1;i++)
{
*s=RcvByte(); /*發送數據*/
Ack_I2c(0); /*發送就答位*/
s++;
}
*s=RcvByte();
Ack_I2c(1); /*發送非應位*/
Stop_I2c(); /*結束匯流排*/
return(1);
}
/*******************************************************************
寫入結束檢測
********************************************************************/
bit Iwcheck(uchar sla)
{
Start_I2c(); //*啟動匯流排
SendByte(sla); //*發送器件地址
if(ack==0)return(0);
//SendByte(c); //*發送數據
// if(ack==0)return(0);
Stop_I2c(); //*結束匯流排
return(1);
}
=======================================
#define A_Data 0x10 //Data在EEPROM中的地址
uchar Data; //一位元組數據
寫入一位元組
if(!ISendStr(0xA0,A_Data,&Data,1))
return FALSE;
return TRUE
if(!IRcvStr(0xA0,A_Data,&Data,1))
return FALSE;
return TRUE;
Ⅹ 關於AVR單片機引用頭文件slavr.h的問題
這個H文件應該不是你的編譯器自帶的文件,所以不是很清楚,就原理而言,你如果要驅動液晶,那麼和液晶連接的幾個引腳是一定要進行初始化配置的,在你的H文件里一定有定義,比如#DEFINE這樣的語句,這樣就把你和液晶連接的幾個引腳用你自己定義的名稱聯系起來了,在根據硬體的連接方式,把DEFINE後面的相應引腳改成適合你硬體的引腳名稱。比如#DEFINE CS PORTA.7,你的電路里CS用的事PORTA.6,那麼你直接把DEFINE後面的PORTA.7改成PORTA.6就可以了,在你的C程序中還是照樣用CS作為你的名字,整個C也不用做修改.(只是舉個例子,在你的編譯器里可能不能識別這樣的位定義,那就要用其它方法進行表示)
如果按照你的說法,那就要自己定義了,其實就是改一個名字就OK了,很容易!看一些單片機相關的程序就明白了