📄 wsaa1064.c
字号:
//参考程序A : WSAA1064.C 功能: SAA1064 驱动四位数码管,显示"3,2,1,0 "
#include <c8051f020.h> // SFR declarations
#define WRITE 0x00 // SMBUS寻址字节的写标志位
#define READ 0x01 // SMBUS寻址字节的读标志位
#define CHIP_B 0x70 //SAA1064器件自身的寻址字节
#define SMB_BUS_ERROR 0x0 //总线错误
//MT为主发送器,MR为主接收器:
#define SMB_START 0x08 // (MT & MR) 发送起始位
#define SMB_RP_START 0x10 // (MT & MR) 重复起始位
#define SMB_MTADDACK 0x18 // (MT) 发送从地址 + W 后收到ACK
#define SMB_MTADDNACK 0x20 // (MT) 发送从地址 + W 后收到NACK
#define SMB_MTDBACK 0x28 // (MT) 发送数据后收到ACK
#define SMB_MTDBNACK 0x30 // (MT) 发送数据后收到NACK
#define SMB_MTARBLOST 0x38 //(MT)竞争失败
#define SMB_MRADDACK 0x40 // (MR) 发送从地址 + R 后收到 ACK
#define SMB_MRADDNACK 0x48 // (MR) 发送从地址 + R 后收到 NACK
#define SMB_MRDACK 0x50 // (MR) 收到数据字节 后已发送ACK
#define SMB_MRDBNACK 0x58 // (MR) 收到数据字节 后已发送NACK
char SLAW,DATA1[64]; // SLAW保存从地址+ WRITE 位
char DATA0[6]={0x17,0x4f,0xb5,0x06,0x3f}; //SAA1064控制码,"3","2","1","0".
char SLAR; // 保存从地址+ READ 位
char WORD,WORDADR; // 保存被收/发的数据字节
char xdata sendnumber; // 保存被收/发的数据字节的数目
//unsigned char xdata WORDADR; //保存被传送的数据在SAA1064中的首地址.
unsigned char xdata SENDMODE;
unsigned char i,j;
bit SM_BUSY;
void SYSCLK_Init (void);
void SMBUS_ISR (void);
char SLA_READ(char sla,char wordadr,char number);
void SLA_SEND(char sla,char wordadr, char word,char number);
void MAIN (void)
{
unsigned char check; // 工作变量 check
WDTCN = 0xde; // 关闭看们狗
WDTCN = 0xad;
SYSCLK_Init(); // 时钟初始化
XBR0 = 0x01; // 选交叉开关 :P0.0-->SDA,P0.1-->SCL
XBR2 = 0x40; // 交叉开关使能
SMB0CN = 0x44; // 允许SMBUS, 应答返回AA(低电平)
SMB0CR = 0x0C9; // SMBus 时钟速率 = 100 kHz(系统时钟为11.0592MHZ)
EIE1 |= 2; // SMBus 中断使能
EA = 1; // 开中断
SM_BUSY = 0; // SM_BUSY是标志位
SI = 0; //SM_BUSY中断标志位
//写5个连续的数据到SAA1064的寄存器中去.要求四位数码显示"0","1","2","3"
//第一个是控制命令(17H),第二到第四个数是四位数码显示的字型码:3FH,06H,5BH,4FH
for (j=0;j<0x6;j++) //向SAA1064的0地址依次写入5个数据,
{ i=DATA0[j];
SLA_SEND(CHIP_B, j, i,0x01 ); //5个数据的数值是:
} // "17H"(控制码),"3FH"("0"),"06H"("1")"5BH"("2"),"4FH"("3")
while(1) ;
}
void SYSCLK_Init (void)
{
int i; /*延时计数器*/
OSCXCN = 0x67; /*启动外部11.0592MHz晶振*/
for (i=0; i < 255; i++) ; /*等待外部晶体起振*/
while ((OSCXCN & 0x80)==0x00) ; /*查询标志位*/
OSCICN = 0x088; /*选择外部晶体作为系统时钟并使能时钟丢失检测*/
}
void SLA_SEND(char sla, char wordadr, char word,char number){
SENDMODE=0x01;
sendnumber=number+1;
while(SM_BUSY); // 若SMBUS忙碌就等待
SM_BUSY = 1; // 置SM_BUSY位(忙碌标志位)为1
SLAW = (CHIP_B| WRITE); // COMMAND = 7 个地址位 + 一位WRITE.
WORD = word; // WORD中存放要送到24C02中去的数据(8位)
WORDADR = wordadr; //WORDADR 中存放被传送数据送入24C02的首地址.
STO = 0;
STA = 1; // 启动数据传输
while(SM_BUSY); // 等待传输完成
}
void SMBUS_ISR (void) interrupt 7 //中断服务程序
{
switch (SMB0STA){ // 根据中断状态码跳转
//(SMB0STA 是中断状态寄存器)
case SMB_START: //0x08, (MT & MR) 发送起始位
SMB0DAT = SLAW ; // 装入被访问的从芯片的写地址
STA = 0; // 人工清除 STA 位
SI = 0; // 清除中断标志位
break;
case SMB_RP_START: //0x10,(MT & MR) 重复发送起始位
SMB0DAT = SLAR; // 装入被访问的从芯片的读地址
STA = 0; // 人工清除 STA 位
SI = 0; // 清除中断标志位
break;
case SMB_MTADDACK: //0x18 ,(MT) 发送从地址 + W 后收到ACK
SMB0DAT = WORDADR;
SI = 0; // 清除中断标志位
break;
case SMB_MTADDNACK: //0x20,(MT) 发送从地址 + W 后收到NACK
STO = 1;
STA = 1;
SI = 0; // 清除中断标志位
break;
case SMB_MTDBACK: //0x28,(MT) 发送数据后收到ACK
switch (SENDMODE){ // 检查低1位
case 1:
sendnumber--;
if(sendnumber)
SMB0DAT = WORD;
else{
STO=1;
SM_BUSY=0;
}
break;
case 0:
STO = 0;
STA = 1;
break;
default:
STO = 1;
SM_BUSY = 0;
break;
}
SI = 0;
break;
case SMB_MTDBNACK: //0x30 (MT) 发送数据后收到NACK
STO = 1;
STA = 1;
SI = 0; // 清除中断标志
break;
case SMB_MRADDACK: //0x40 (MR) 发送从地址 + R 后收到 ACK
AA = 0; // 回送NACK
SI = 0;
break;
case SMB_MRADDNACK: //0x48 (MR) 发送从地址 + R 后收到 NACK
STO = 0;
STA = 1;
SI = 0;
break;
case SMB_MRDBNACK: //0x58 (MR) 收到数据字节 后已发送NACK
WORD = SMB0DAT;
STO = 1;
SM_BUSY = 0;
AA = 1; // AA置1
SI = 0;
break;
default:
STO = 1;
SM_BUSY = 0;
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -