📄 bc7281.c
字号:
/******************************************************************************
函数:Bc7281.c
入口参数:LoopCount, mcu中断次数
出口参数:无
底层硬件函数说明:
(1)向BC7281发送一个字节 SendByte_7281(unsigned char send_byte)
(2)从BC7281接收一个数据字节 ReceiveByte_7281(void)
(3)向BC7281写入一个字节
Write_7281(unsigned char reg_add unsigned char write_data)
(4)从BC7281读出一个数据字节 Read_7281(unsigned char reg_add)
(5)写读7281位传送中的延时函数 Delay(unsigned char delay_time)
MCU向BC7281写入一个字节通信协议(MCU发送,BC7281接收):
(1)MCU向BC7281写入一个字节需通过发送两个字节完成,前一个为指令字节,后
一个才为数据字节;
(2)在接口空闲的情况下,BC7281的DAT引脚处于高阻输入状态,而MCU端也应将
DAT线置于输入状态,上拉电阻使得DAT引脚处于高电平;
(3)传送开始时,首先要建立握手信号,MCU先向BC7281发出一系列CLK脉冲,同时
监测DAT电平的变化,当BC7281收到握手脉冲后在DAT线上输出一低电平,表示
可以接收MCU数据,MCU一旦检测到BC7281的响应信号后,立即停止发送握手脉
冲,并在规定时间内在CLK线上再发出一个脉冲,使得BC7281的DAT引脚恢复高
阻输入状态,由于DAT引脚接有上拉电阻,故DAT恢复成高电平;
(4)MCU检测到DAT恢复成高电平之后,即开始发送数据 (指令字节或数据字节),发
送时数据的高位(MSB)在前,每发送一位需输出一个CLK脉冲,CLK脉冲均为下降
沿有效。
MCU从BC7281读出一个数据字节通信协议(BC7281发送,MCU接收):
(1)MCU从BC7281读出一个字节, 由MCU向BC7281写入一个指令字节和从BC7281读
出一个数据字节两部分组成;
(2)MCU在传送指令字节后,应将DAT线置于输入状态,以便从BC7281接收数据;
(3)MCU读数据时,需建立握手信号,过程与写入数据相似。但不必像写入数据时
发一系列脉冲,只需发一个脉冲即可。具体过程是:MCU首先向BC7281发出一个
脉冲,BC7281在收到脉冲后在DAT线上响应一个低电平,表示准备好输出数据,
此后MCU再发出一个脉冲,BC7281的DAT脚即开始跟随MCU的每一个脉冲输出一
位数据;
(4)与写入指令不同的是,当8个数据位均读出以后,MCU还必须再多发出一个脉冲,
表示数据接收完毕,BC7281才能从数据输出状态转成输入状态,准备接收下一
个指令。
******************************************************************************/
// 包含文件声明
#include "DSP281x_Device.h" // DSP281x Headerfile Include File
#include "DSP281x_Examples.h" // DSP281x Examples Include File
#define uchar unsigned char
// MCU I/O端口定义
#define Clk_In GpioMuxRegs.GPBDIR.bit.GPIOB11=0
// 定义 Clk_In 为SCL(CPU.71)输入
#define Clk_Out GpioMuxRegs.GPBDIR.bit.GPIOB11=1
// 定义 Clk_Out 为SCL(CPU.71)输出
#define Setb_Clk GpioDataRegs.GPBSET.bit.GPIOB11=1
// 定义 Setb_Clk 为:置SCL(CPU.71)高电平
#define Clr_Clk GpioDataRegs.GPBCLEAR.bit.GPIOB11=1
// 定义 Clr_Clk 为:置SCL(CPU.71)低电平
#define Dat GpioDataRegs.GPDDAT.bit.GPIOD6
// 定义 Dat 为 CPU.83脚,用于接收信号
#define Dat_In GpioMuxRegs.GPDDIR.bit.GPIOD6=0
// 定义 Dat_In 为SDA(CPU.83)输入
#define Dat_Out GpioMuxRegs.GPDDIR.bit.GPIOD6=1
// 定义 Dat_Out 为SDA(CPU.83)输出
#define Setb_Dat GpioDataRegs.GPDSET.bit.GPIOD6=1
// 定义 Setb_Dat 为:置SDA(CPU.83)高电平
#define Clr_Dat GpioDataRegs.GPDCLEAR.bit.GPIOD6=1
// 定义 Setb_Dat 为:置SDA(CPU.83)低电平
#define KEY GpioDataRegs.GPDDAT.bit.GPIOD5
// 定义 KEY 为 CPU.79脚,用于接收信号
#define KEY_In GpioMuxRegs.GPDDIR.bit.GPIOD5=0
// 定义 KEY_In 为KEY(CPU.79)输入
//被调用函数声明
void SendByte_7281(unsigned char);
unsigned char ReceiveByte_7281(void);
void Write_7281(unsigned char reg_add, unsigned char write_data);
unsigned char Read_7281(unsigned char reg_add);
void Delay(unsigned char);
Uint16 g=0,s=0,b=0,q=0,w=0; // 变量始值定义,g,s,b,q,w分别对应LED的
// 个,十,百,千,万位
Uint16 Disp_Tab[16]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e };
// LED数码管"0-f"显示译码表
extern Uint16 count; // 声明count为外部变量,否则不能引用
// 初始化函数
// 初始化程序,将CLK和DAT均置为数字IO,将CLK置为输出高,DAT置为输入
// 4位LED显示数字由全局变量中断次数参数LoopCount传递
/******************************************************************************
函数:LedH_Display()
共用体(union)说明:
共用体包含2个成员: 一个是16位无符号数i,另一个是包含(low,mid0,mid1,high)
4个(半字节)变量的结构体。它们共占同一个内存单元。通过对i(p.i)进行赋值,
可以完成对结构体4个变量的赋值。
功能: 将模数转换值以16进制两个字节形式,在Led第8,7,6,5位数码管上进行显示
******************************************************************************/
void LedH_Display(void) // 7281初始化函数
{
Uint16 count_buf;
count_buf=0;
if(count_buf!=count) // 当count_buf!=count_时,执行下面语句
// 否则保留原值,以免Led数码管频繁闪烁
{
union
{
Uint16 i; // 定义i为双字节
struct
{
Uint16 low:4; // 低位在前,高位在后
Uint16 mid0:4; // 低位在前,高位在后
Uint16 mid1:4; // 仅取低字节
Uint16 high:4;
}q;
}p;
p.i=count;
q=p.q.high;
b=p.q.mid1;
s=p.q.mid0;
g=p.q.low;
count_buf=count; // 更新count_buf数据
EALLOW; // 允许访问受保护的空间
Clk_Out; // 设定连接CLKK(7281.3)的
// TDIRB"CPU.71"为输出(时钟输出)
Dat_In; // 设定连接DATT(7281.1)的
// T4CTRIP"CPU.83"为输入(回馈接收)
EDIS; // 禁止访问受保护的空间
Setb_Clk;
Write_7281(0x12,0x80); // 初始化BC728x为164模式不反相
Write_7281(0x10,0xFF);
//Write_7281(0,Disp_Tab[g]); // 向LED个位(3位)写"g"数据
//Write_7281(1,Disp_Tab[s]); // 向LED十位(2位)写"s"数据
//Write_7281(2,Disp_Tab[b]); // 向LED百位(1位)写"b"数据
//Write_7281(3,Disp_Tab[q]); // Write_7281(3,Disp_Tab[d]&0x7f)
// 加小数点;
// 向LED千位(0位)写"q"数据,
// 以上4行通过译码表由程序译码
Write_7281(0x15,0x40+g); // 向LED千位(0位)写"g"数据,
// 以下4行为通过片内译码器0x15
// 由硬件进行Hex译码。显然硬件译码
// 比程序译码速度快
Write_7281(0x15,(0x50+s)); // 向LED百位(1位)写"s"数据
Write_7281(0x15,(0x60+b)); // 向LED十位(2位)写"b"数据
Write_7281(0x15,(0x70+q)); // 向LED个位(3位)写"q"数据
//Write_7281(0x18,0x0bf); // 消除第8位Led的小数点,该小数点是
// 在以十进制显示
// 模数转换值时出现的
}
}
/******************************************************************************
函数: LedD_Display()
功能: 将模数转换值以10进制形式,在Led第4,3,2,1位数码管上进行显示
******************************************************************************/
void LedD_Display(void) // 7281初始化函数
{
Uint16 count1;
// Uint32 k;
count1=count;
q=(int)(count1/1000); // q为(count1/1000)的整数部分,
count1=count1-q*1000; // 当count1<1000时,q=0
b=(int)(count1/100); // b为(count1/100)的整数部分,
count1=count1-b*100; // 当count1<100时,b=0
s=(int)(count1/10); // s为(count1/10)的整数部分,
count1=count1-s*10; // 当count1<10时,s=0
g=(int)(count1); // 余数为个位数g
/*
count1=count;
q=(int)(count1/1000); // d为(count1/1000)的整数部分,
//当count1<1000时,d=0
count1=count1-q*1000;
b=(int)(count1/100); // c为(count1/100)的整数部分,
// 当count1<100时,c=0
count1=count1-b*100;
s=(int)(count1/10); // b为(count1/10)的整数部分,
// 当count1<10时,b=0
count1=count1-s*10;
g=(int)(count1); // 余数为个位数a
*/
EALLOW; // 允许访问受保护的空间
Clk_Out; // 设定连接CLKK(7281.3)的
// TDIRB"CPU.71"为输出
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -