串口通讯问题
我使用ADS7886做模数转换,但结果总死在第一个 while(!(IFG2 & UCA0RXIFG))这里了。。
麻烦哪位高手帮下忙,万分感谢!!!
void init_spi()
{
P3DIR |=0X41;
P3SEL |=0X21;
UCA0CTL0 |=UCMSB+UCMST+UCSYNC;//3线8位spi
UCA0CTL1 |=UCSSEL_2;
UCA0BR0 |=0X02;
UCA0BR1 |=0X00;//通讯速率smclk/2 1mhz
UCA0CTL1 &=~UCSWRST;//复位不允许
}
void ad_convert(uint data)
{
uchar dat1,dat2;
setcs;
//_NOP();
clrcs;
//_NOP();
IFG2 &= ~UCA0RXIFG;
UCA0TXBUF =0X00;//写无用值启动spi
while(!(IFG2 & UCA0RXIFG))//RXBUF准备好没?接收到数据没有? 程序死在这儿!!!!!
dat1=UCA0RXBUF;//接受高字节
UCA0TXBUF =0X00;//写无用值启动spi
while(!(IFG2 & UCA0RXIFG))//RXBUF准备好没?接收到数据没有?
dat2=UCA0RXBUF;//接受低字节
data=dat1&0x000f;
data=data<<8;
data+=dat2;
}
认真看下ADS7886,它的串口并不是SPI总线。
它的通讯脚包括CS/,CLK,SDO,看下数据手册的时序图,用软件实现串口的数据读取吧。
用的是msp430f2618
法1: 硬件spi
P3SEL |= 0x31; // P3.5,4,0 option select
UCA0CTL0 |= UCMST+UCSYNC+UCCKPL+UCMSB+UCCKPH; //3-pin, 8-bit SPI master
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 = 0x10; // /2
UCA0BR1 = 0; //
UCA0MCTL = 0; // No modulation
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
// IE2 |= UCA0RXIE; // Ena××e USCI_A0 RX interrupt
ADS7886_CS_DIR = 1;
ADS7886_CS = 1;
unsigned int ads7886_spi_read()
{
unsigned int data = 0;
ADS7886_CS = 0;
while (!(IFG2 & UCA0TXIFG)); // USCI_B0 TX buffer ready?
UCA0TXBUF = 0x55;
while (!(IFG2 & UCA0RXIFG)); // USCI_B0 TX buffer ready?
data = UCA0RXBUF;
while (!(IFG2 & UCA0TXIFG)); // USCI_B0 TX buffer ready?
UCA0TXBUF = 0x55;
while (!(IFG2 & UCA0RXIFG)); // USCI_B0 TX buffer ready?
data = (data<<8)|UCA0RXBUF;
ADS7886_CS = 1;
return (data&0x0fff);
}
法2 : io模拟
void ads7886_init()
{
ADS7886_SCLK_DIR = 1;
ADS7886_CS_DIR = 1;
ADS7886_SDO_DIR = 0;
ADS7886_SCLK = 1;
ADS7886_CS = 1;
}
unsigned int ads7886_read_data()
{
unsigned char i = 0;
unsigned int data = 0;
ADS7886_SCLK = 1;
ADS7886_CS = 0;
for(i=0; i<16; ++i)
{
data <<= 1;
ADS7886_SCLK = 1;
if(ADS7886_SDO)
data |= 0x0001;
else
data &= 0xfffe;
ADS7886_SCLK = 0;
}
ADS7886_SCLK = 1;
ADS7886_CS = 1;
return (data&0x0fff);
}
//第二个下降沿~第十个下降沿中间 降cs置高
void ads7886_power_down()
{
unsigned char i = 0;
ADS7886_SCLK = 1;
ADS7886_CS = 0;
for(i=0; i<3; ++i)
{
ADS7886_SCLK = 0;
ADS7886_SCLK = 1;
}
ADS7886_CS = 1;
}
//A dummy cycle with CS low for more than 10 SCLK falling edges brings the device out of power down mode.
//cs拉低10个时钟周期以上
void ads7886_wake_up()
{
unsigned char i = 0;
ADS7886_SCLK = 1;
ADS7886_CS = 0;
for(i=0; i<12; ++i)
{
ADS7886_SCLK = 0;
ADS7886_SCLK = 1;
}
ADS7886_CS = 1;
}
可能地没处理好,误差比430自带ad大点 - -!
UCA0CTL0 |= UCMST+UCSYNC+UCCKPL+UCMSB+UCCKPH; //3-pin, 8-bit SPI master
这里注意下就好了
为什么呢?CKPH和CKPL只是设置的时钟的有效信号和极性对数据输入输出之间的关系啊,我的设置方法怎么有问题呢?谢谢
看ADS7886手册时序 ,sclk高的时候读sdo
本人感觉430的SPI的速度和哦牛一般,慢的不行,而且在12**系列中还要暂用串口的寄存器(不能同时用),我直接用普通IO口,三根线,写的SPI,传输速率快多了,可靠性也高,不占用串口资源。