调试SPI通信,读从设备寄存器里面数据老是不对,求教
#include <iom8v.h>#include <macros.h>
#define uint8 unsigned char
#define uint16 unsigned int
/*-----------------RN8209--------------------------*/
uint8 Write_enable={0xE5};// 写使能
uint8 IARMS={0};//通道A电流有效值
#defineRN8209_MOSI3
#defineRN8209_MISO4
#defineRN8209_SCK 5
#define CLR8209PORTB&=~(1<<PB0); //CS为低电平,使能SPI
#define SET8209 PORTB|= (1<<PB0);
#define RN8209_IARMS 0x7f//通道A电流有效值
//数码管定义15E显示板 0-9 空
uint8 SegTab={0x77,0x12,0xD5,0xD6,0xB2,0xE6,0xE7,0x52,0xF7,0xF6,0x00,0x80,0xF1,0x65,0x61,0xF3,0x97,0xA7,0x81};
uint8 Up_Disbuff={1};
uint8 Middle_Disbuff={1};
uint8 Down_Disbuff={1};
/* -----------------数码显示扫描缓冲区------------------*/
uint8Axx={0x00,0x04,0x02,0x06};//译码地址
/*--------------------延时---------------------*/
void delay_us(uint16 us)
{
uint16 i;
us=us*5/4;
for(i=0;i<us;i++);
}
void delay_ms(uint16 ms)
{
uint16 i,j;
for(i=0;i<ms;i++)
for(j=0;j<1141;j++);
}
/*--------------------74HC164输入数据----------------*/
void write_164(uint8 ChrDat)
{
uint8 i;
for(i=8;i>0;i--)
{
if(ChrDat&0x80)// 输出数据
PORTD|=(1<<PD5);//PD5为74HC164的数据输入端,置1
else
PORTD&=~(1<<PD5);//置0
ChrDat<<=1;
PORTD&=~(1<<PD7); //PD7为74HC164的时钟信号,置0
PORTD|=(1<<PD7); //时钟给上升延信号,置1
}
}
/*-------------------74F138输入口数据--------------------*/
voidout138(uint8 x)
{
uint8 i;
i= PORTC & 0xF8 ;
x= x & 0x07 ;
PORTC = i | x ;
}
/*--------------------刷新显示一次的程序--------------------*/
voiddisplay(void)
{
uint8 temp_address = 0 ;
for(temp_address=0;temp_address<4;temp_address++)
{
PORTC=0x07;//消影
write_164(SegTab]);
write_164(SegTab]);
write_164(SegTab]);
out138(Axx);//显示
delay_ms(1);//延时1ms
}
}
/*-----------RN8209读写函数-----------------------*/
void Reset_RN8209(void)
{
SET8209;
delay_us(10);
PORTB&=~(1<<RN8209_SCK);//时钟拉低
CLR8209;//拉低
delay_us(10);
}
voidWrite_RN8209_Byte(uint8wdata)
{
uint8i ;
for(i=0;i<8;i++)
{
PORTB&=~(1<<RN8209_SCK);//时钟拉低
if(wdata&0x80)//先发高位,上升沿
{
PORTB|=(1<<RN8209_MOSI);
}
else
{
PORTB&=~(1<<RN8209_MOSI);
}
delay_us(10);
PORTB|=(1<<RN8209_SCK);//时钟拉高
wdata<<=1;
}
}
uint8 Read_RN8209_Byte(void)
{
uint8 i,rdata;
for(i=0;i<8;i++)
{
rdata<<1;
PORTB|=(1<<RN8209_SCK); //读数据时为下降沿读出
delay_us(10);
PORTB&=~(1<<RN8209_SCK);//时钟拉低
delay_us(10);
if(PINB&(1<<RN8209_MISO))
{
rdata|=0x01;
}
}
returnrdata;
}
void Write_RN8209_Reg(uint8 regn, uint8 *data, uint8 num)
{
Reset_RN8209();
Write_RN8209_Byte(regn|0x80);//命令寄存器最高位为1表示写,写命令寄存器+芯片解析+响应命令
while(num--)
{
Write_RN8209_Byte(data);//单字节高位在前地位在后。多字节高字节在前,低字节在后
}
PORTB&=~(1<<RN8209_SCK);//拉低时钟端
delay_us(10);
SET8209;//拉高片选端
}
void Read_RN8209_Reg(uint8 regn,uint8 *data,uint8 num)
{
Reset_RN8209();
Write_RN8209_Byte(regn&0x7f);//命令寄存器最高位为0表示读
while(num--)
{
data = Read_RN8209_Byte();//以字节为传输高比特在前,低比特在后;多字节传输先传高字节再传低字节
}
PORTB&=~(1<<RN8209_SCK);//拉低时钟端
delay_us(10);
SET8209;//拉高片选端
}
/*long Hex_To_Dex(uint8 *data,uint8 num)
{
uint8 i;
long k=0;
for(i=0;i<(num-1);i++)
{
k|=data;
k<<=8;
}
return k;
}*/
void Init_RN8209(void)
{
Write_RN8209_Reg(0xEA,Write_enable,1);//写使能
}
void main(void)
{
//long temp;
PORTB=0x00;
DDRB=0x2D;//设置MISO(PB4)为输入,高电平;MOSI(PB3) ,SCK(PB5) 和SS(PB2)为输出,高电平
//0010 1101
PORTC=0x07;
DDRC=0x07;//74HC138控制端CBA输为输出
PORTD=0xE0;//74HC164的CLR为PD6刚开始为高
DDRD=0xE0;
Init_RN8209();
while(1)
{
if(PIND&(1<<PD2))
{
Read_RN8209_Reg(RN8209_IARMS,IARMS,3);
//temp=Hex_To_Dex(IARMS,3);
Up_Disbuff=IARMS>>4;
Up_Disbuff=IARMS&0x0f;
Up_Disbuff=IARMS>>4;
Up_Disbuff=IARMS&0x0f;
Middle_Disbuff=IARMS>>4;
Middle_Disbuff=IARMS&0x0f;
}
display();
}
} 本帖最后由 bbxyliyang08 于 2012-12-20 21:23 编辑
附上从设备资料,我是读寄存器7f里面的值,因为这里面的值是固定的是820900H,由于我这板子没JTAG接口,只能通过数码管显示出来,同时也附上我们项目的原理图,搞不出来就得走人,社会就这么现实,各位大侠们,帮帮忙,小弟不胜感激。
页:
[1]