上周开始做STM32采集编码器输出的SSI信号,并采用SSI信号的形式输出。
由于是始终脉冲上升沿触发数据发送,因此决定采用EXTI中断的方式,当时钟脉冲上升沿时,触发中断函数中的数据传递部分。SSI信号的波形时序如下图
现在波形和数据都是正确的,但是数据和波形会跳闪,不知道是什么原因,应该怎么解决?麻烦各位帮我看看代码有什么错误吧!
[mw_shl_code=c,true]#include "stm32f10x.h"
#include <stdio.h>
#include<math.h>
#include<zcharmlib.h>
#include"stm32f10x_spi.h"
#define CLKOUT PB6 //STM32时钟脉冲给751177-----CLKOUT
#define DATAIN PB8in //751177数据给STM32 -----DATAIN
#define CLKIN PB9in //仪表给STM32时钟脉冲 -----CLKIN
#define DATAOUT PB5 //STM32数据给仪表 -----DATAOUT
#define uchar unsigned char
#define uint unsigned int
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
u8 mod_addr=0;
u8 re_i_cmp=0,de_i_cmp=0,re_end=0;
u8 re_array_cmp[5]={0,0,0,0,0},de_array_cmp[8]={0,0,0,0,0,0,0,0};
u8 re_array_ggj[22]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22},re_i_ggj=0;
u8 temp_m1=0,temp_m2=0;
u32 grey_bian=0,bin_bian_a1=0,bcd_bian;
u8 i_fa_asii=0, bian_bcd[5]={0,0,0,0,0};
u8 bian_bcd_asii[9]={0,0,0,0,0,0,0,0,0};
u8 tx_temp1=0,rx_temp1=0,it_temp1=0;
uchar data5045[4]={0,0,0,0};
u8 send_data[27]={1,0,0,1,1,0,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,1,1,0,1,1};
int counter=0;
int times=0;
//通用初始化函数
void RCC_Configuration(void);
void GPIO_Configuration(void);
void USART_Configuration(void);
void EXTI_Configuration(void);
void NVIC_Configuration(void);
/*定义延时函数*/
void delay(vu32 nCount)
{for(; nCount != 0; nCount--);}
/*****函数名称:1ms延时函数*****/
void delayms(unsigned z)
{
unsigned x,y;
for(x=z;x>0;x--)
for(y=1580;y>0;y--);
}
//25格雷码转换成25位二进制码
u32 graytobin(u32 x)
{
u32 y=x;
while(x>>=1)
y^=x;
return y;
}
//编码器采集程序
u32 read_bian()
{
u32 gray_bian_temp1=0;
u8 gray_bit[27];
int i;
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0f;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0f;
NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
NVIC_Init(&NVIC_InitStructure);
CLKOUT=0;
gray_bit[26]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[24]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[23]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[22]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[21]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[20]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[19]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[18]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[17]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[16]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[15]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[14]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[13]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[12]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[11]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[10]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[9]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[8]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[7]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[6]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[5]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[4]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[3]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[2]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[1]=DATAIN;
CLKOUT=1;
CLKOUT=0;
gray_bit[0]=DATAIN;
CLKOUT=1;
gray_bit[25]=DATAIN;
send_data[26]=gray_bit[26];
for(i=0;i<=24;i++)
{
send_data[i+1]=gray_bit;
}
send_data[0]=gray_bit[25];
times=0;
// EXTI_ClearITPendingBit(EXTI_Line9);
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0f;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0f;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
for(u8 i=27;i>0;i--)
{
gray_bian_temp1=(gray_bian_temp1|gray_bit[i-1])<<1;
}
return gray_bian_temp1>>1;
}
/****************************主函数程序段*************************************/
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
NVIC_Configuration();
EXTI_Configuration();
//IWDG_Configuration();
while(1)
{
//int i;
u32 shuju;
shuju=read_bian();
//shuju=graytobin(shuju);//编码器信号接收以及gray转binary
delayms(30);
}
}
/*******************************************************************************
* Function Name : RCC_Configuration
* Description : 系统时钟设置
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void RCC_Configuration(void)
{
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON); // Enable HSE
ErrorStatus HSEStartUpStatus;
HSEStartUpStatus = RCC_WaitForHSEStartUp(); // Wait till HSE is ready
if(HSEStartUpStatus == SUCCESS)
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_2);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
RCC_PLLCmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while(RCC_GetSYSCLKSource() != 0x08)
{
}
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA| RCC_APB2Periph_GPIOB
|RCC_APB2Periph_GPIOC| RCC_APB2Periph_AFIO, ENABLE);
//启动GPIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|
RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD ,ENABLE);
//启动AFIO 开启EXTI中断要用
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
}
/*******************************************************************************
GPIO设置
#define CLKOUT PB6 //STM32时钟脉冲给751177-----CLKOUT
#define DATAIN PB8in //751177数据给STM32 -----DATAIN
#define CLKIN PB9in //仪表给STM32时钟脉冲 -----CLKIN
#define DATAOUT PB5 //STM32数据给仪表 -----DATAOUT
*******************************************************************************/
void GPIO_Configuration(void)
{
//PB口
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_5|GPIO_Pin_6;
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_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/*******************************************************************************
* Function Name : EXTI_Configuration
1. 开启GPIO时钟--RCC完成
2. 配置GPIO复用功能--GPIO完成
3. 开启AFIO时钟--RCC完成
4. 指定EXTI引脚--EXTI0必须对应PA0...PG0中之一;EXTI1必须对应PA1...PG1中之一
5. 配置EXTI引脚--EXTI的第几脚;工作方式(事件、中断);触发方式(上升、下降、上升 和下降
6. 开启EXTI中断--
*******************************************************************************/
void EXTI_Configuration(void)
{
/* Connect EXTI9 Line to PB9 pin */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource9);
/* Configure EXTI3 line */
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line9;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;// 上升沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
/*******************************************************************************
* Function Name : NVIC_Configuration
* Description : NVIC设置
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void NVIC_Configuration(void)
{
//串口USART1中断相关
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
//串口USART2中断相关
NVIC_InitStructure.NVIC_IRQChannel=USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
//EXTI中断相关
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0f;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0f;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*******************************************************************************
* Function Name : EXTI9_5_IRQHandler
* Description : This function handles External lines 9 to 5 interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
extern u8 send_data[27];
extern int counter;
extern int times;
#define DATAOUT PB5
void EXTI9_5_IRQHandler(void)
{
//if(EXTI_GetITStatus(EXTI_Line9)!=RESET)
if(times<=25)
{
DATAOUT=send_data[25-times];
times++;
}
if(times>25)
{
DATAOUT=0;
delay(8);
DATAOUT=1;
times=0;
delay(100);
}
EXTI_ClearITPendingBit(EXTI_Line9);
}[/mw_shl_code]
|