📄 mast_spi.c
字号:
#include"stc89c58rd.h"
#include<string.h>
#include<intrins.h>
sbit sdo = P1^3; //主出从入 P1^5 <-----> P1^3 写出
sbit sdi = P1^2; //主入从出 P1^6 <-----> P1^2 读入
sbit spi_clk = P3^3; //时钟 P1^7 <-----> P3^3
unsigned char spi_packet = 0;
unsigned char read_flag = 0;
void run_disp()
{
unsigned int i,j;
for(i=0;i<100;i++)
{
for(j=0;j<500;j++)
{
;
}
}
}
void spi_init(void)
{
spi_clk= 1; //空闲时高电平 ??
sdo = 1;
sdi = 1;
}
/*******************************************************************************************************
********* 将 STC12C4052配置成从机模式,先传LSB,上升沿数据输入,下降沿数据输出 *****************
***** SSIG = 1,忽略/SS脚。SPEN = 1允许SPI工作。DORD = 1先传LSB;(0先传MSB)。MSTR =0设为从机。********
******** CPOL = 0,时钟在空闲时为0;CPOL = 1,时钟在空闲时为1。上升CPOL = 0或下降 CPOL = 1
******** CPHA=0,在串行同步时钟的“第一个跳变沿”(上升或下降)数据被采样。CPOL = 1上升数据输入,下降数据输出。
******** CPHA=1,在串行同步时钟的“第二个跳变沿”(上升或下降)数据被采样。CPOL = 1上升数据输入,下降数据输出。
******** SPR1、0 = 00 FOSC/4 参考P132 Fig5mast = 1 数据在mosi输出,mast = 0 数据在miso输出
******************* 时钟极性和相位配置正确后,数据才能够被准确的发送和接收********************************
******** 主设备的SDO同从设备的SDO配置一致,主设备的SDI同从设备的SDI配置一致 主设备这边的时钟极性和相位都是
******** 以从设备为基准的。在时钟极性的配置上一定要搞清楚从设备是在时钟的上升沿还是下降沿接收数据。是在时
*** 钟的下降沿还是上升沿发送数据。另外由于主设备的SDO连接从设备的SDI,从设备的SDO连接主设备的SDI,
*** 从设备SDI接收的数据是主设备的SDO发送过来的,主设备SDI接收的数据是从设备SDO发送过来的,所以主设备这边
*** SPI时钟极性的配置(即SDO的配置)跟从设备的SDI接收数据的极性是相反的,跟从设备SDO发送数据的极性是相同的。
*** “主设备在时钟的下降沿发送数据,从设备在时钟的上升沿接收数据”。因此主设备这边SPI时钟极性应该配置为下降沿有效
***“从设备在时钟的上升沿接收数据,因此主设备的SPI时钟极性同样应该配置为下降沿有效”
********************************************************************************************************************/
/** SPI 读写一体化
***** STC12C4054 先上升沿数据输入SDI,后下降沿数据输出SDO。**********
***** STC89C58RD+ 先上升沿数据输出SDO,后下降沿数据输入SDI。
*/
#define _d_spi_receive_buffer_size 1
unsigned char spi_receive_buffer[_d_spi_receive_buffer_size];
unsigned char bchar;
void init_serialcomm(void)
{
SCON = 0x50; //SCON: serail mode 1, 8-bit UART, enable ucvr
PCON = 0x00; //SMOD=0;
ET1 = 0; //禁止定时器1中断
// AUXR = 0x00; //T0,T1 12分频0001,11xx。T0,T1,UART_M0,ADC,ESPI,LVDI,X,X
TMOD = 0x20; //TMOD: timer 1, mode 2, 8-bit reload
TH1 = 0xfd; //Baud:9600 fosc=11.0592MHz
TL1 = 0xfd;
TR1 = 1; // timer 1 run
ES = 1; //IE = 0x90Enable Serial Interrupt
}
void spi_write(unsigned char val) //先下降沿输出后上升沿读入
{
unsigned char i;
for(i=8;i>0;i--)
{
spi_clk = 0; //第一个跳变
_nop_();_nop_();_nop_();
sdo = (bit)(val & 0x01); //数据写到MOSI线(mosi spi输入) 先发LSB
_nop_();_nop_();_nop_();
val = val >>1;
spi_clk = 1; //第二个跳变,上升沿数据输出
_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();
}
sdo = 1;
_nop_();_nop_();_nop_();
spi_clk = 1;
_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();
}
unsigned char spi_read()
{
unsigned char i;
sdi = 1;
for(i=0;i<8;i++)
{
spi_clk = 1;
_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();
spi_clk = 0;
_nop_();_nop_();_nop_();
CY = sdi; //下降沿数据输出
_nop_();_nop_();_nop_();
_rrca_(); //右移,存数据到ACC.7
_nop_();_nop_();_nop_();
}
spi_clk = 1;
sdi = 1;
return ACC;
}
void get_spi()
{
/* unsigned char i;
for(i=0;i<_d_spi_receive_buffer_size;i++)
{
spi_receive_buffer[i] = spi_read();
}
spi_packet = 1;*/
bchar = spi_read();
spi_packet = 1;
}
void send_char_com(unsigned char ch)
{
SBUF=ch;
while(TI==0);
TI=0;
}/*
//向串口发送一个字符串,strlen为该字符串长度
void send_string_com(unsigned char *str,unsigned char strlen)
{
unsigned int k=0;
do
{
send_char_com(*(str + k));
k++;
} while(k < strlen);
}
*/
main()
{
init_serialcomm();
spi_init(); //初始化串口
EA = 1;
while(1)
{
spi_write(0x55);
run_disp();
/*
spi_write(0x33);
spi_write(0xff); */
get_spi();
if(spi_packet) //如果取数标志已置位,就将读到的数从串口发出
{
spi_packet=0; //取数标志清0
// send_string_com(spi_receive_buffer,_d_spi_receive_buffer_size);
send_char_com(bchar);
bchar = 0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -