论坛» 企业专区» Microchip

PIC24FJ128GA106单片机SPI模块通信问题

助工
2014-10-13 15:54 1楼

利用PIC24FJ128GA106单片机SPI2模块与计量芯片进行数据通信,分别向计量芯片的寄存器写入数据,然后再读取数据,写入数据时序,数据很正确,但是读取时就不正确了,几乎没有数据回来,不知道问什么,请各位大神帮帮忙,万分感谢!一下是部分程序:


void SPI2Init(void)
{
//config SPI2
SPI2STATbits.SPIEN = 0; // disable SPI port
SPI2STATbits.SPISIDL = 0; // Continue module operation in Idle mode


SPI2BUF = 0; // clear SPI buffer


IFS2bits.SPI2IF = 0; // clear interrupt flag
IEC2bits.SPI2IE = 0; // disable interrupt


SPI2CON1bits.DISSCK = 0; // Internal SPIx clock is enabled
SPI2CON1bits.DISSDO = 0; // SDOx pin is controlled by the module
SPI2CON1bits.MODE16 = 0; // set in 8-bit mode, clear in 16-bit mode
SPI2CON1bits.SMP = 0; // 在数据位的中间位置采样
SPI2CON1bits.CKP = 0; // SCLK 高电平有效,SCK空闲时为低电平
SPI2CON1bits.CKE = 0; // SCLK 上升沿数据按位从SDO输出
SPI2CON1bits.MSTEN = 1; // 1 = Master mode; 0 = Slave mode
SPI2CON1bits.SPRE = 3; // Secondary Prescaler = 5:1
SPI2CON1bits.PPRE = 1; // Primary Prescaler = 16:1


SPI2CON2 = 0; // non-framed mode


SPI2STATbits.SPIEN = 1; // enable SPI port, clear status
}


void SPI2RPn(void) //SPI2 assign to RPN
{
__builtin_write_OSCCONL(OSCCON & 0xbf); //clear the bit 6 of OSCCONL to unlock Pin Re-map, unlock register
RPOR11bits.RP22R = 11; //11 represents SCK2, Assign SCK2 To Pin RP22
RPOR11bits.RP23R = 10; //10 represents SDO2, Assign SDO2 To Pin RP23
RPINR22bits.SDI2R = 24; //24 represents RP24,Assign SDI2 to Pin RP24
__builtin_write_OSCCONL(OSCCON | 0x40); // Lock Registers,set the bit 6 of OSCCONL to lock Pin Re-map
}

uchar writeSPI2Buf( uchar data )
{
SPI2BUF = data; // write to buffer for TX
while(!SPI2STATbits.SPIRBF);
return SPI2BUF; // read the received value
}//writeSPI2




long SPI2_Read4Byte( uint address) //read SPI data
{
long w,z,x,y,data;
int i;
// CSx = 0;
SPI_CS8_PORT=0;
writeSPI2Buf(CMD_read); //读命令,包含寄存器地址
for (i=0; i<0x0f; i++);
x= writeSPI2Buf(address); //32位数据,读取高8位数据
y= writeSPI2Buf(address); //32位数据,读取中高8位数据
z= writeSPI2Buf(address); //32位数据,读取中低8位数据
w= writeSPI2Buf(address); //32位数据,读取低8位数据
x= (x<<8)+y;
x=x<<8;
data= (x<<8)+(z<<8)+w; // 合并高低数据
for (i=0; i<0x0f; i++);
SPI_CS8_PORT=1;
// CSx = 1;
return data;
}
long SPI2_Read3Byte( uint address) //read SPI data
{
long z,x,y,data;
int i;
// CSx = 0;
SPI_CS8_PORT=0;
writeSPI2Buf(CMD_read); //读命令,包含寄存器地址
for (i=0; i<0x0f; i++);
x= writeSPI2Buf(address); //24位数据,读取高8位数据
y= writeSPI2Buf(address); //24位数据,读取中8位数据
z= writeSPI2Buf(address); //24位数据,读取低8位数据
x= x<<8;
data= (x<<8)+(y<<8)+z; // 合并高低数据
for (i=0; i<0x0f; i++);
SPI_CS8_PORT=1;
// CSx = 1;
return data;
}
uint SPI2_Read2Byte( uint address) //read SPI data
{
uint x,y,data;
int i;
// CSx = 0;
SPI_CS8_PORT=0;
writeSPI2Buf(CMD_read); //读命令,包含寄存器地址
for (i=0; i<0x0f; i++);
x= writeSPI2Buf(address); //16位数据,读取高8位数据
y= writeSPI2Buf(address); //16位数据,读取中8位数据
data= (x<<8)+y; // 合并高低数据
for (i=0; i<0x0f; i++);
SPI_CS8_PORT=1;
// CSx = 1;
return data;
}


void SPI2_WriteByte(uint data, uint address) //SPI write data
{
uint n;
int i;
// CSx = 0;
SPI_CS8_PORT=0;
n= writeSPI2Buf(CMD_write); //写命令,包含寄存器地址
for (i=0; i<0x0f; i++);
n= writeSPI2Buf(Hi(data)); //写高8位数据
n= writeSPI2Buf(Lo(data)); //写低8位数据
for (i=0; i<0x0f; i++);
SPI_CS8_PORT=1;
// CSx = 1;
}
void SPI2_Write1Byte(uint data, uint address) //SPI write data
{
uint n;
int i;
// CSx = 0;
SPI_CS8_PORT=0;
n= writeSPI2Buf(CMD_write); //写命令,包含寄存器地址
for (i=0; i<0x0f; i++);
n= writeSPI2Buf(data); //写高8位数据
// n= writeSPI2Buf(Lo(data)); //写高8位数据
for (i=0; i<0x0f; i++);
SPI_CS8_PORT=1;
// CSx = 1;
}
void SPI2_WriteByteEN(uint data, uint address) //SPI writeEN
{
uint n;
// CSx = 0;
SPI_CS8_PORT=0;
n= writeSPI2Buf(address);
n= writeSPI2Buf(data);
SPI_CS8_PORT=1;
// CSx = 1;
}


int main(void)
{
uint i,txData,rxData,R,x;
SPI2RPn();
SPI2Init();
SPI_CS();

for (i=0; i<0x0f; i++);


SPI2_WriteByteEN(WREN, 0xEA); // 8209 SPI writeEN
SPI2_WriteByte(0x0081, EMUCON); //计量控制寄存器设定
SPI2_WriteByte(0x0000, SYSCON); //系统控制寄存器设定.
SPI2_WriteByte(0x2892, HFConst); //HFConst参数设置.
SPI2_WriteByte(0xC26D, GPQA); //A通道有功增益校正.
SPI2_Write1Byte(0x28, PhsA); //A通道有功相位校正.
SPI2_WriteByte(0x01BB, APOSA); //A通道有功offse校正
SPI2_WriteByte(0xEFBF, IARMSOS); //A通道电流有效值偏置校正
SPI2_WriteByteEN(WRPT, 0xEA); // 8209 SPI write protect







for (i=0; i<0x0f; i++);


txData= SPI2_Read2Byte(EMUCON);
rxData= SPI2_Read2Byte(APOSA);
R= SPI2_Read2Byte(GPQA);
x= SPI2_Read2Byte(HFConst);



while(1); // Success
}

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册]