📄 spi.h
字号:
#define NOP asm volatile("nop\n\t"::)
#define RESET asm volatile("jmp 0x0000": : )
#define Adjust5532Run 0
#define ReadSADC5532Run 0
#define ReadMADC5532Run 1
#define CS5532SDI PB5
#define CS5532SDO PB6
#define CS5532CLK PB7
#define set_5532A() PORTE&=~(1<<PE0);DDRE|=(1<<PE0)//使能AD1
#define cle_5532A() PORTE|=(1<<PE0);DDRE|=(1<<PE0)//禁止AD1
#define set_5532B() PORTE&=~(1<<PE2);DDRE|=(1<<PE2)//使能AD1
#define cle_5532B() PORTE|=(1<<PE2);DDRE|=(1<<PE2)//禁止AD1
#define CLK_0() PORTB&=~(1<<PB7);DDRB|=(1<<CS5532CLK)//CLK引脚置零
#define SDI_0() PORTB&=~(1<<PB5);DDRB|=(1<<CS5532SDI)//SDI引脚置零
#define judje_SDO (PINB&(1<<PB6))//判断SDO引脚是否为1
#define judje_PBO (PINB&(1<<PB0))//测试用
void wait_SDO(void)
{uchar n;
for(n=30;(judje_SDO)&&(n>0);n--)
{
_delay_ms(1);
}
}
/*************************************
功能:选择CS5532
参数:one:0x0a选择A,0x0b选择B
返回值:无
编写人:王志辉
时间:2007年6月2日
*************************************/
void Selec_cs5532(uchar one)
{
if(one==0xa0)
{
set_5532A();
cle_5532B();
}
else
{
set_5532B();
cle_5532A();
}
}
/*************************************
功能:取消CS5532
参数:one:0x0a选择A,0x0b选择B
返回值:无
编写人:王志辉
时间:2007年6月2日
*************************************/
void Del_cs5532(void)
{
cle_5532B();
cle_5532A();
}
/*
0x81; // 自偏移校准
0x82; // 自增益校准
0x85; // 偏移校准
0x86; // 增益校准
*/
//CS5532命令数据结构
typedef struct{
uchar top;
uchar high;
uchar mid;
uchar low;
}CS5532_value;
CS5532_value RegDat;
CS5532_value value_CS5532A[1024];
CS5532_value value_CS5532B[1024];
/*************************************
功能:初始化SPI(从机,模式0,1/16分频)
参数:无
返回值:无
编写人:王志辉
时间:2007年6月2日
*************************************/
void init_SPI(void)
{
SPCR = (0<<SPIE)|(1<<SPE)|(0<<DORD)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA)|(0<<SPR1)|(1<<SPR0);
SPSR = (0<<SPIF)|(0<<WCOL)|(0<<SPI2X);
//SPIE -------------1SPI中断使能,0中断禁止
//SPE--------------1使能SPI,0禁止SPI
//DORD -------------数据次序 1低位先发,0高位先发
//MSTR -------------1主机,0从机
//CPOL,CPHA ----------SPI模式选择
//SPI2X,SPI1X,SPI0X------SPI时钟频率设置(从机时不能高于系统时钟的1/4)
//SPIF -------------SPI中断标志位
//WCOL -------------写碰撞标志位
PORTB|=(1<<CS5532SDI);//SDI引脚
DDRB|=(1<<CS5532SDI);
PORTB|=(1<<CS5532SDO);//SDO引脚
DDRB&=~(1<<CS5532SDO);
PORTB|=(1<<CS5532CLK);//CLK引脚
DDRB|=(1<<CS5532CLK);
}
/*************************************
功能:SPI主机发送一字节数据
参数:DAT要发送的命令
返回值:无
编写人:王志辉
时间:2007年6月2日
*************************************/
void SendByte5532(uchar Dat)
{
SPDR=Dat;
loop_until_bit_is_set(SPSR,SPIF);//等待spi传输完毕
}
/*************************************
功能:SPI主机读取一字节数据
参数:无
返回值:读取值
编写人:王志辉
时间:2007年6月2日
*************************************/
uchar ReceiveByte5532(void)
{
SPDR=0x00;
loop_until_bit_is_set(SPSR,SPIF);//等待spi传输完毕
return SPDR;
}
/*************************************
功能:写5532的寄存器
写寄存器发送命令后发送四个八位数据共32位数据
参数:command:命令码
low:数据内容
mid:数据内容
high:数据内容
top:数据内容
返回值:无
编写人:王志辉
时间:2007年6月2日
*************************************/
void WriteReg5532(uchar cs,uchar command,uchar low,uchar mid,uchar high,uchar top)
{
Selec_cs5532(cs);
SendByte5532(command);
SendByte5532(low);
SendByte5532(mid);
SendByte5532(high);
SendByte5532(top);
Del_cs5532();
}
/*************************************
功能:读取单次转换AD值
参数:command:单次转换命令
返回值:无
编写人:王志辉
时间:2007年6月2日
*************************************/
#if ReadSADC5532Run
void ReadSADC5532(uchar cs,uchar command)
{
Selec_cs5532(cs);
SendByte5532(command);
do{NOP;CLK_0();SDI_0();}while(judje_SDO);
SendByte5532(0x00);//8bit SCLK and SDI=0;
RegDat.top = ReceiveByte5532();
RegDat.high = ReceiveByte5532();
RegDat.mid = ReceiveByte5532();
RegDat.low = ReceiveByte5532();
Del_cs5532();
}
#endif
/*************************************
功能:读取连续转换AD值
参数:command:0x00为继续为连续转换,0xff为结束单次转换模式
返回值:无
编写人:王志辉
时间:2007年6月2日
*************************************/
#if ReadMADC5532Run
void ReadMADC5532(uchar cs,uchar command)
{
Selec_cs5532(cs);
do{NOP;}while(judje_SDO);
SendByte5532(command);//8bit SCLK and SDI=command;
RegDat.top = ReceiveByte5532();
RegDat.high = ReceiveByte5532();
RegDat.mid = ReceiveByte5532();
RegDat.low = ReceiveByte5532();
Del_cs5532();
}
#endif
#if Adjust5532Run
void Adjust5532(unsigned char command)
{
Selec_cs5532(cs);
SendByte5532(command);
do{NOP;}while(judje_SDO);
SendByte5532(0x0a);
RegDat.top = ReceiveByte5532();
RegDat.high = ReceiveByte5532();
RegDat.mid = ReceiveByte5532();
RegDat.low = ReceiveByte5532();
Del_cs5532();
}
#endif
/*************************************
功能:发送初始化序列
参数:无
返回值:无
编写人:王志辉
时间:2007年6月2日
*************************************/
void Send_Init5532(uchar cs)
{
WriteReg5532(cs,0xff,0xff,0xff,0xff,0xff);
WriteReg5532(cs,0xff,0xff,0xff,0xff,0xff);
WriteReg5532(cs,0xff,0xff,0xff,0xff,0xff);
WriteReg5532(cs,0xff,0xff,0xff,0xff,0xfe);
}
//ad初始化
void Init5532A(uchar cs)
{
uchar b=0;
uchar data;
Del_cs5532();
NOP;
Selec_cs5532(cs);//选择5532A
NOP;
Send_Init5532(cs);//发送初始化序列
WriteReg5532(cs,0x03,0x20,0x00,0x00,0x00);//写CS5532配置寄存器,进行初始化RS位置1系统复位
while(data!=0x10)//等待ad复位
{
b++;
Selec_cs5532(cs);//使能cs5532
SendByte5532(0x0b);//读配置寄存器
data=ReceiveByte5532();//等待RS变0,RV置1,即初始化成功
ReceiveByte5532();
ReceiveByte5532();
ReceiveByte5532();
send_one(cs+data); //测试用;返回初始化成功的代码
SendByte5532(0x81);//自偏移校准
wait_SDO();
send_one(cs+2); //测试用;返回初始化成功的代码
SendByte5532(0x82);//自增益校准
wait_SDO();
send_one(cs+3); //测试用;返回初始化成功的代码
Del_cs5532();//禁止cs5532
_delay_ms(1);
if(b>20)
{
RESET;
}
}
WriteReg5532(cs,0x03,0x00,0x00,0x00,0x00);//写CS5532配置寄存器初始化电压参考模型 1V<=Vref<=VA+
WriteReg5532(cs,0x05,0x34,0x00,0x00,0x00);//选择通道寄存器选择通道1,增益1,3.840Khz,单极性
Selec_cs5532(cs);//选择5532A
SendByte5532(0xc0);//连续转换
Del_cs5532();//禁止cs5532
}
/*************************************
功能:串口1接收中断
参数:无
返回值:无
编写人:王志辉
时间:2007年6月4日
是否测试:是
*************************************/
SIGNAL(SIG_USART1_RECV)
{
recive_buf[recive_length]=UDR1;
recive_length++;
if(recive_length>=5)
{
ReadMADC5532(0xa0,0xff);
WriteReg5532(0xa0,recive_buf[0],recive_buf[1],recive_buf[2],recive_buf[3],recive_buf[4]);
Selec_cs5532(0xa0);//选择5532A
SendByte5532(0xc0);//连续转换
Del_cs5532();//禁止cs5532
ReadMADC5532(0xb0,0xff);
WriteReg5532(0xb0,recive_buf[0],recive_buf[1],recive_buf[2],recive_buf[3],recive_buf[4]);
Selec_cs5532(0xb0);//选择5532A
SendByte5532(0xc0);//连续转换
Del_cs5532();//禁止cs5532
recive_length=0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -