淘的一个max31856现成的模块,附送了Arduino范例和一个FreeRTOS的范例,恰恰对这两个很陌生,便根据max31856文档改成了STC15的第二组spi接口((P2.4///SPISS, P2.3/MOSI_2, P2.2/MISO_2, P2.1/SCLK_2))。
无论用stcisp中stc15的spi单主单从范例,还是虚拟spi,读出的寄存器值都是0xFF(255)。
可以确定接线没问题,如果接线错误读出的就是0x00.
原理图:
代码如下:
- //本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
- //若无特别说明,工作频率一般为11.0592MHz
- #include "reg51.h"
- #include<stdio.h>
- #include<intrins.h>
- #define FOSC 11059200UL
- #define BAUD 115200
- typedef unsigned char BYTE;
- typedef unsigned int WORD;
- typedef unsigned char u8;
- typedef unsigned int u16;
- #define SR_Read 0x0F
- #define URMD 0 //0:使用定时器2作为波特率发生器
- //1:使用定时器1的模式0(16位自动重载模式)作为波特率发生器
- //2:使用定时器1的模式2(8位自动重载模式)作为波特率发生器
- sfr P1M1 = 0x91; //PxM1.n,PxM0.n =00--->Standard, 01--->push-pull
- sfr P1M0 = 0x92; // =10--->pure input, 11--->open drain
- sfr P0M1 = 0x93;
- sfr P0M0 = 0x94;
- sfr P2M1 = 0x95;
- sfr P2M0 = 0x96;
- sfr P3M1 = 0xB1;
- sfr P3M0 = 0xB2;
- sfr P4M1 = 0xB3;
- sfr P4M0 = 0xB4;
- sfr P5M1 = 0xC9;
- sfr P5M0 = 0xCA;
- sfr P6M1 = 0xCB;
- sfr P6M0 = 0xCC;
- sfr P7M1 = 0xE1;
- sfr P7M0 = 0xE2;
- sfr T2H = 0xd6; //定时器2高8位
- sfr T2L = 0xd7; //定时器2低8位
- sfr AUXR = 0x8e; //辅助寄存器
- sfr P_SW1 = 0xa2; //外设功能切换寄存器1
- #define SPI_S0 0x04 //P_SW1.2
- #define SPI_S1 0x08 //P_SW1.3
- sfr SPSTAT = 0xcd; //SPI状态寄存器
- #define SPIF 0x80 //SPSTAT.7
- #define WCOL 0x40 //SPSTAT.6
- sfr SPCTL = 0xce; //SPI控制寄存器
- #define SSIG 0x80 //SPCTL.7
- #define SPEN 0x40 //SPCTL.6
- #define DORD 0x20 //SPCTL.5
- #define MSTR 0x10 //SPCTL.4
- #define CPOL 0x08 //SPCTL.3
- #define CPHA 0x04 //SPCTL.2
- #define SPDHH 0x00 //CPU_CLK/4
- #define SPDH 0x01 //CPU_CLK/16
- #define SPDL 0x02 //CPU_CLK/64
- #define SPDLL 0x03 //CPU_CLK/128
- sfr SPDAT = 0xcf; //SPI数据寄存器
- sbit SPISS = P2 ^ 4; //SPI从机选择口, 连接到其它MCU的SS口
- //当SPI为一主多从模式时,请使用主机的普通IO口连接到从机的SS口
- sfr IE2 = 0xAF; //中断控制寄存器2
- #define ESPI 0x02 //IE2.1
- void InitUart();
- void InitSPI();
- u16 WenDu;
- u8 WenDu_Time, Error;
- BYTE SPISwap(BYTE dat);
- u8 SPI_RW_Reg(u8 reg, u8 value);
- ///////////////////////////////////////////////////////////
- void Delay500ms(void) //@11.0592MHz
- {
- unsigned char data i, j, k;
- _nop_();
- _nop_();
- i = 22;
- j = 3;
- k = 227;
- do
- {
- do
- {
- while (--k);
- }
- while (--j);
- }
- while (--i);
- }
- void main()
- {
- u16 x, y;
- P0M0 = 0x00;
- P0M1 = 0x00;
- P1M0 = 0x00;
- P1M1 = 0x00;
- P2M0 = 0x00;
- P2M1 = 0x00;
- P3M0 = 0x00;
- P3M1 = 0x00;
- P4M0 = 0x00;
- P4M1 = 0x00;
- P5M0 = 0x00;
- P5M1 = 0x00;
- P6M0 = 0x00;
- P6M1 = 0x00;
- P7M0 = 0x00;
- P7M1 = 0x00;
- InitUart(); //初始化串口
- InitSPI(); //初始化SPI
- IE2 |= ESPI;
- EA = 1;
- while (1)
- {
- Delay500ms() ;
- x = SPISwap(0x00);//00~0F 都是只读配置reg
- y = SPISwap(0x01);
- printf("MAX31856_Read00:%d ;Read01:%d\n", x, y);
- }
- }
- BYTE SPISwap(BYTE dat)
- {
- SPDAT = dat; //触发SPI发送数据
- while (!(SPSTAT & SPIF)); //等待发送完成
- SPSTAT = SPIF | WCOL; //清除SPI状态位
- return SPDAT; //返回SPI数据
- }
- //SPI写寄存器
- //reg:指定寄存器地址
- //value:写入的值
- u8 SPI_RW_Reg(u8 reg, u8 value)
- {
- u8 status;
- status = SPISwap(reg); //返回从MISO读出的数据,status应为上次向该寄存器内写的value
- SPISwap(value); //写入寄存器的值
- return status; // 返回状态值
- }
- ///////////////////////////////////////////////////////////
- void InitUart()
- {
- SCON = 0x5a; //设置串口为8位可变波特率
- #if URMD == 0
- T2L = (65536 - (FOSC / 4 / BAUD));
- T2H = (65536 - (FOSC / 4 / BAUD)) >> 8;
- AUXR = 0x14; //T2为1T模式, 并启动定时器2
- AUXR |= 0x01; //选择定时器2为串口1的波特率发生器
- #elif URMD == 1
- AUXR = 0x40; //定时器1为1T模式
- TMOD = 0x00; //定时器1为模式0(16位自动重载)
- TL1 = (65536 - (FOSC / 4 / BAUD));
- TH1 = (65536 - (FOSC / 4 / BAUD)) >> 8;
- TR1 = 1; //定时器1开始启动
- #else
- TMOD = 0x20; //设置定时器1为8位自动重装载模式
- AUXR = 0x40; //定时器1为1T模式
- TH1 = TL1 = (256 - (FOSC / 32 / BAUD));
- TR1 = 1;
- #endif
- }
- ///////////////////////////////////////////////////////////
- void InitSPI()
- {
- ACC = P_SW1; //可用于测试U7,U7使用的是第二组SPI控制Flash
- ACC &= ~(SPI_S0 | SPI_S1); //SPI_S0=1 SPI_S1=0
- ACC |= SPI_S0; //(<b>P2.4///SPISS, P2.3/MOSI_2, P2.2/MISO_2, P2.1/SCLK_2</b>)
- P_SW1 = ACC;
- SPDAT = 0; //初始化SPI数据
- SPSTAT = SPIF | WCOL; //清除SPI状态
- SPCTL = SPEN | MSTR; //设置SPI为主模式
- //SPCTL = SPEN | MSTR | SSIG | SPDLL; //主机模式 忽略SS引脚
- }
复制代码 有没遇到同类问题的高手请指点一下。
原资料包:
MAX31856模块资料.zip
(1.47 MB, 下载次数: 1)
|