完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
大家好,我是一个单片机自学新人。没有导师,很多问题光靠百度是解决不了的。每个人遇到的问题都不一样。偶然看到电子发烧友网站。希望在这里可以得到大家的提点。
这两天我在实验SPI通讯。用了两片STC12C5A60S2(网上申请的样片),自带SPI硬件接口的。 本想达到的目的是。其中一个芯片做主机,另外一个做从机。 主机由UART串口发送一个数据,通过SPI串口发送到从机, 从机收到数据后用1602液晶显示出来,并且向主机返回接收到的数据,然后 在串口小助手里显示从机返回的值。 可是在主机发送程序端就出现了问题。 我通过几处添加串口小助手接收子程序UART_SendByte() 发现问题出在,向SPDAT写入数据时,无法写进数据。 SPDAT总是0XFF。 下面是主机程序。能帮我分析一下,为什么写不进去吗?还有那个CPU_CLK/16分频 有什么影响吗?这个MCU是1T的单片机,但是我没有开,用的是默认的12T的。 /* SPI主机程序,无中断串口接收并用SPI发送--------------------------------------- --------------------------------------------------------------------*/ #include #define SPIF ( SPSTAT & 0x80 ) //查询SPIF是否置位,SPIF不能进行位操作 /*通信端口设置-------------------------------------------------------*/ ***it SCLK = P1^7; ***it MISO = P1^6; ***it MOSI = P1^5; ***it SS = P1^4; unsigned char UART_SendData=0; unsigned char UART_RecData=0; unsigned char SPI_RecData=0; void Init_System(); void Init_UART(); void Init_SPI(); unsigned char SPI_SendByte(unsigned char SPI_SendData); void UART_SendByte(unsigned char UART_Send); void main() { Init_System(); while(1) { /* 查询UART接收信号 ----------------------------------*/ while(!RI); //查看串口是否接收到数据 { RI=0; //当接收到数据后,清除接收中断标志 UART_RecData=SBUF; //读入数据 UART_SendData=SPI_SendByte(UART_RecData);//将收到的数据由SPI发送出去,又接收回来 UART_SendByte(UART_SendData); } } } /*--------------------------------------------------------- *函数名:Init_System *函数功能:系统初始化 *输入参数:无 *返回参数:无 ----------------------------------------------------------*/ void Init_System() { Init_UART(); Init_SPI(); } /*--------------------------------------------------------- *函数名:Init_UART *函数功能:串口初始化,无中断方式 *输入参数:无 *返回参数:无 ----------------------------------------------------------*/ void Init_UART() { TMOD=0x20;//设置定时器1为工作方式2 TH1=0xF3; //波特率为2400,晶振为12MHz TL1=0xF3; TR1=1; //启动T1 REN=1; //串行允许位 // PCON=0x80; //PCON寄存器的SMOD位置一,波特率提高一倍 SM0=0; SM1=1; //串行方式1 // ES=1; //中断接收则开串口中断,查询接收则关闭此句 } /*--------------------------------------------------------- *函数名:Init_SPI *函数功能:SPI初始化,SPI的工作方式,不使用SPI中断方式 *输入参数:无 *返回参数:无 ----------------------------------------------------------*/ void Init_SPI() { SPCTL = 0xfc;//CPU_CLK/16,时钟前沿为下降沿,后沿采样,主模式,最低位在前,SPI使能 1111 1101 SPSTAT = 0xc0;//SPDAT.7和SPDAT.6写11,可以将中断标志清零。注意是写1才清零 } /*--------------------------------------------------------- *函数名:SPI_SendByte *函数功能:SPI发射接收一体程序 *输入参数:SPI_SendData,经主机发给从机的数据 *返回参数:从机发给主机的数据 ----------------------------------------------------------*/ unsigned char SPI_SendByte(unsigned char SPI_SendData) { SPDAT= SPI_SendData; //将串口接收的数据装入SPI数据寄存器 UART_SendByte(SPDAT); while(!SPIF);//等待发送完毕 SPSTAT = 0xc0; //清除中断标志,和写冲突标志,注意是对应位写1才能清零 SPI_RecData = SPDAT; UART_SendByte(SPDAT); return SPI_RecData; } /*--------------------------------------------------------- *函数名:UART_SendByte *函数功能:串口发送 *输入参数:UART_Send *返回参数:无 ----------------------------------------------------------*/ void UART_SendByte(unsigned char UART_Send) { ti = 0; //清除发送SBUF空标志 SBUF = UART_Send; //写入SBUF while (!TI); //等待发送完毕 TI = 0; //清除发送SBUF空标志 } |
|
相关推荐
24个回答
|
|
UART_SendByte(SPI_SendData);改成这样试一下,看数据到底正常不,然后看一下接线正常不
|
|
|
|
这是我自己写的关于SPI模块的程序,你参考参考吧 //SPI从机程序 #include #include #define uchar unsigned char #define uint unsigned int /************对SPCTL寄存器的设置位宏定义*************/ #define SSIG 0x80 //SS引脚忽略 #define SPEN 0x40 //SPI使能位 #define DORD 0x20 //SPI数据发送LSB最先发送 #define MSTR 0x10 //主从模式选择 #define CPOL 0x08 //SPICLK空闲时为高电平 #define CPHA 0x04 //数据在SPICLK的前时钟沿驱动,并在后时钟沿采样 #define SP_CLK0 0x00 //SPI时钟频率为CPU_CLK/4 #define SP_CLK1 0x01 //SPI时钟频率为CPU_CLK/16 #define SP_CLK2 0x02 //SPI时钟频率为CPU_CLK/64 #define SP_CLK3 0x03 //SPI时钟频率为CPU_CLK/128 /************对SPSTAT寄存器的设置位宏定义************/ #define SPIF 0x80 //传输完成标志 #define WCOL 0x40 //SPI写冲突标志 /************SPI口切换宏定义***************/ #define SPI_P4 0x20 //SPI从P1口切换到P4口 /************波特率选择********************/ #define BTL 9600 //若要更改波特率直接更改此处,当波特率大于9600时需修改相应的接收程序, //可选波特率有以下: 否则有可能出现乱码 //波特率为2400 //波特率为28800 //波特率为4800 //波特率为38400 //波特率为9600 //波特率为57600 //波特率为14400 //波特率为115200 //波特率为19200 void UART_init(void); uchar Receive(void); void Printf( uchar *p ); void Init_SPI(void); void Send_byte( uchar byte ); //****************************************// // 串口初始化 // //****************************************// void UART_init(void) { // SM0 = 0; //选择串口为方式1工作 // SM1 = 1; //8位数据波特率可变 // REN = 1; //允许串口接收 SCON = 0x50; #if( BTL == 2400 ) BRT = 0x70; //波特率设置为9600 #elif( BTL == 4800 ) BRT = 0xB8; #elif( BTL == 9600 ) BRT = 0xDC; #elif( BTL == 14400 ) BRT = 0xE8; #elif( BTL == 19200 ) BRT = 0xEE; #elif( BTL == 28800 ) BRT = 0xF4; #elif( BTL == 38400 ) BRT = 0xF7; #elif( BTL == 57600 ) BRT = 0xFA; #elif( BTL == 115200 ) BRT = 0xFD; #endif AUXR = 0x15; //选择独立波特率发生器为串行 //口的波特率发生器,模式为1T // ES = 1; //允许串口中断 // IPH = 0X10; //PSH = 1; // IP = 0X10; //PS = 1;串口1中断为最高优先级中断 // EA = 1; //开总中断 } //************************************************// // 发送一个字节数据 // //************************************************// void Send_byte( uchar byte ) { SBUF = byte; while(!TI); TI = 0; } //************************************************// // 打印字符 // //************************************************// void Printf( uchar *p ) { while( *p != ' |