请教各位大神,用stm32驱动的cs5530,用的是模拟SPI,用串口发到上位机,时而能采集到数,但是大多时候采集的是0.时而采到的数是正确的,猜想还是模拟SPI哪里出现了问题。请问各位大神有什么好的解决办法吗,这个软件调试、时钟和sdi都能正常写指令的,用示波器看 时钟质量非常不好,sdi看不到数据 sdo根本没有。- #include "cs5530.h"
- #include "delay.h"
- #include "sys.h"
- //毫秒级延时函数
- #define TIME 1
- #define SET_ADCS PBout(15)=1;
- #define CLR_ADCS PBout(15)=0;
- #define SET_ADSCK PBout(12)=1; //spiSCK输出高
- #define CLR_ADSCK PBout(12)=0; //spiSCK输出低
- #define SET_ADI PBout(14)=1; //MOSI输出高
- #define CLR_ADI PBout(14)=0; //MOSI输出低
- #define GET_ADO PBin(13) //MISO输入高
- void CS5530_PORT_INIT( void ) /* 由于使用软件模拟SPI读写时序,所以进行初始化 */
- {
-
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE); //使能pc端口时钟
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14|GPIO_Pin_12|GPIO_Pin_15; //
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOB,&GPIO_InitStructure);
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
-
- /* 对于双向I/O引脚模拟SPI接口,那么必须在此设置SPI_SCS,SPI_SCK,SPI_SDI为输出方向,SPI_SDO为输入方向 */
-
- }
- void Write_CS5530(unsigned char Dat)
- {
-
- unsigned char Count;
- for( Count=0; Count<8; Count++ )
- {
- if(Dat & 0x80)
- {SET_ADI;}
- else
- {CLR_ADI;}
- delay_us(1);
- SET_ADSCK;
- delay_us(1);
- CLR_ADSCK;
- delay_us(1);
- Dat <<= 1;
- }
- CLR_ADI;
- delay_us(1);
-
- }
- //
- unsigned char Recive_CS5530(void)
- {
- unsigned char Count;
- unsigned char Dat=0;
- CLR_ADI;
- delay_us(3);
- for( Count=0; Count<8; Count++ )
- {
- SET_ADSCK;
- delay_us(1);
- Dat <<= 1;
- if( GET_ADO ) Dat |= 0x01 ;
- CLR_ADSCK;
- delay_us(1);
- }
- return(Dat);
- }
- void Write_CS5530_Register(unsigned char Command,unsigned long setData)
- {
- Write_CS5530( Command );
- Write_CS5530( (unsigned char)(setData>>24) );
- Write_CS5530( (unsigned char)(setData>>16) );
- Write_CS5530( (unsigned char)(setData>>8) );
- Write_CS5530( (unsigned char)(setData>>0) );
- }
- unsigned long Read_CS5530_Register(unsigned char Command)
- {
- unsigned long temp=0;
- Write_CS5530( Command );
- temp = Recive_CS5530();
- temp = temp << 8;
- temp += Recive_CS5530();
- temp = temp << 8;
- temp = Recive_CS5530();
- temp = temp << 8;
- temp += Recive_CS5530();
- return temp;
- }
- void Init_CS5530(void)
- {
- unsigned long temp;
- unsigned char i;
- // SPI IO 初始化行为
- CS5530_PORT_INIT();
- CLR_ADSCK;
- CLR_ADCS;
- delay_ms(100);
- // SPI 串口归位
- for( i=0; i<20; i++ )
- {
- Write_CS5530(SYNC1);
- }
- Write_CS5530(SYNC0);
- // 系统复位
- Write_CS5530_Register(Write_CONFIG,SYSTEM_RESET); //写配置寄存器写入 CS5530RS 为 1
- delay_ms(50);
- do
- {//检测 RV 是否为 0(复位成功后为 0),如果不为 0 再继续读取配置寄存器
- temp = Read_CS5530_Register( Read_CONFIG );
- } while( temp & RESET_STATUS );
- // 设置偏移寄存器
- Write_CS5530_Register(Write_OFFSET,0x00000000);
- delay_ms(50);
- // 设置增益寄存器
- Write_CS5530_Register(Write_GAIN,0x0f000000);
- delay_ms(50);
- // 设置配置寄存器,设置参考电压,信号极性,字速度等等
- //Write_CS5530_Register(Write_CONFIG,0x02004800);
- //Delay_ms(50);
- temp = 0x00;
- temp |= UNIPOLAR_MODE; // 单极性
- temp |= LINE_FREQ_50; // 滤波选择缺省滤波字
- temp |= DATARATE_25;
- temp |= NORMAL_MODE; // 普通操作
- temp |= VREF_LOW; // VREF_HIGH 为 2.5V 基准; VREF_LOW 为 1-2.5V 基准
- temp |= CR_A0_0;
- temp |= CR_A1_0;
- temp |= TURN_OFF_300NA; // 不激活电流源
- Write_CS5530_Register(Write_CONFIG,temp);
- delay_ms(50);
- //启动转换
- Write_CS5530( START_CONTINUOUS + NORMAL_CONVERSION); // 单次转换
- }
- // 读取数据转换的结果
- unsigned long Get_Ad(void)
- {
- unsigned long temp;
- do //等待转换完成
- {
- ;
- }while(GET_ADO);
- CLR_ADI;
- Write_CS5530( NULL_BYTE ); // 清除串口标志同时选择转换模式(单次连续还是结束单次连续)
- temp = Recive_CS5530();
- temp = temp << 8;
- temp += Recive_CS5530();
- temp = temp << 8;
- temp += Recive_CS5530();
- temp = temp << 8;
- temp += Recive_CS5530();
- //Write_CS5530( START_SINGLE + NORMAL_CONVERSION); // 单次转换
- return temp;
- }
- #ifndef __CS5530_H__
- #define __CS5530_H__
- #include "delay.h"
- #include "sys.h"
- //------------------------------------
- //-- CS5530 专有宏定义
- #define SYNC1 0xff //串行口初始化序列命令之一
- #define SYNC0 0xfe //串行口初始化序列结束命令
- #define NULL_BYTE 0x00 //用来清除端口标志位使得转换器保持在连续转换模式
- #define CMD_WRITE (0x00<<3) // 写寄存器命令
- #define CMD_READ (0x01<<3) // 读寄存器命令
- //Command Register
- #define Write_OFFSET 0x01 //写偏移寄存器
- #define Read_OFFSET 0x09 //读偏移寄存器
- #define Write_GAIN 0x02 //写增益寄存器
- #define Read_GAIN 0x0a //读增益寄存器
- #define Write_CONFIG 0x03 //写配置寄存器
- #define Read_CONFIG 0x0b //读配置寄存器
- #define START_SINGLE (0X00<<6) //单次转换
- #define START_CONTINUOUS (0X01<<6) //连续转换
- #define NORMAL_CONVERSION (0x80+0x00)//转换命令
- #define SYSTEM_OFFSET_CAL 0x85 //执行系统偏移校准
- #define SYSTEM_GAIN_CAL 0x86 //执行系统增益校准
- //Configuration Register
- #define STANDBY_MODE (0x00L<<31) //待机模式
- #define SLEEP_MODE (0x01L<<31) //休眠模式
- #define POWER_SAVE_MODE (0x01L<<30) //节电模式
- #define NORMAL_MODE (0x00L<<29) //正常操作
- #define SYSTEM_RESET (0x01L<<29) //激活一个复位周期复位后自动清0
- #define RESET_STATUS (0x01L<<28) //复位有效系统已复位只读
- //#define SHORT_INPUTS (0x00L<<27) //输入正常输入个通道输入不断接
- #define SHORT_INPUTS (0x01L<<27) //输入正常输入个通道输入不断接
- #define VREF_HIGH (0x00L<<25) //参考电压 2.5~((VA+)-(VA-))V
- #define VREF_LOW (0x01L<<25) //参考电压 1~2.5V
- #define CR_A1_0 (0x00L<<24)
- #define CR_A1_1 (0x01L<<24)
- #define CR_A0_0 (0x00L<<23)
- #define CR_A0_1 (0x01L<<23)
- #define LINE_FREQ_60 (0x00L<<19) //滤波数率选择缺省输入字
- #define LINE_FREQ_50 (0x01L<<19) //输出字数率及相应滤波器特性乘以系数5/6
- #define DATARATE_100 (0x00L<<11) //字数率不同位就不同
- #define DATARATE_50 (0x01L<<11)
- #define DATARATE_25 (0x02L<<11)
- #define DATARATE_12P5 (0x03L<<11)
- #define DATARATE_6P25 (0x04L<<11)
- #define DATARATE_3200 (0x08L<<11)
- #define DATARATE_1600 (0x09L<<11)
- #define DATARATE_800 (0x0aL<<11)
- #define DATARATE_400 (0x0bL<<11)
- #define DATARATE_200 (0x0cL<<11)
- #define DATARATE_BIT (0x0fL<<11)
- #define BIPOLAR_MODE (0x00L<<10) //极性选择双极性模式
- #define UNIPOLAR_MODE (0x01L<<10) //极性选择单极性模式
- #define TURN_OFF_300NA (0x00L<<9) //不激活电流源
- #define TURN_ON_300NA (0x01L<<9) //激活电流源 300ma
- void Init_CS5530(void);
- unsigned long Get_Ad(void);
- //void CS5530_PORT_INIT( void );
- #endif
|