基于STM32实现sBus协议数据获取、解析并转为CAN协议数据

本文目录:

1、功能实现情况

2、实现路线

3、关于sBus共地问题的注意事项

4、结语

1、功能实现情况

        目前该装置可以实现将航模接收机输出的sBus协议数据进行获取并根据sBus协议进行解析,最终经CAN总线将解析之后的数据传输出去。目前为功能实现阶段,暂时将解析之后的11位数据(在stm32中,数据的存储类型为uint16_t)舍弃掉部分位之后转为8位数据(在stm32中数据的存储类型为uint8_t)经CAN总线传输出去。

2、实现路线

       图1为数据的传输方向示意图,也为装置的实现路线图。其中遥控器和接收机使用的型号为云卓T10,有10个通道,接收机5V供电,接收机输出信号选择sBus协议信号。

e001c32bb4784631b05a8e166840791d.jpeg

图1:实现路线

        其中从遥控器发送数据到接收机以及硬件取反电路组成实现路线第一段;在实现路线第一段基础上加上STM32组成实现路线第二段,最后在实现路线第二段的基础上加上CAN总线收发器模块组成实现路线第三段,至此,输出的数据为CAN协议数据。

        至于为什么在接收机和STM32之间加上硬件取反电路是由sBus协议内容要求的,关于sBus协议内容参考资料:不清楚SBUS,这份SBUS协议详解请收藏_振华OPPO的博客-CSDN博客

需特别注意sBus在STM32中串口参数的配置。

2.1、实现路线第一段 

      该段需要注意的事项为接收机的5V供电,其中5V供电的正极需和实现路线第二段中的STM32的ST-Link上5V针脚连接,5V供电的负极需和STM32的GND引脚连接(至于为什么这样连接详见本文文末“关于装置电源共地问题的注意事项”),STM32系统选择STM32F103C8T6最小系统板。此外,还需注意的事项为硬件取反电路的3.3V供电,如果3.3V供电的正极和STM32的3.3V引脚连接可能会出现硬件取反电路不工作的情况,问题可能为STM32板子上的3.3V引脚的驱动能力不强,此时可能需要外接3.3V的电源,此处对于硬件取反电路没有和STM32共地的要求。

        检验实现路线第一段是否成功实现需要一个USB转串口模块,如图2、图3所示,具体操作为:将接收机上的正负极暂时分别与ST-Link的5V针脚和STM32的GND脚断开,并将其分别于USB转串口模块上的5V与GND连接,然后将搭载了 经取反电路转换后的sBus数据 的信号线与USB转串口接线端上的Rx引脚连接,打开串口调试助手并设置好串口调试助手相关通信参数,其通信参数的具体值参考sBus协议中对波特率、奇偶校验位、停止位等的要求。

c3c7d35330564878b3c857b23c9902ba.jpeg

图2:USB转串口模块正面

cefa9fa04da74275872711dcdb2a9187.jpeg

图3:USB转串口模块反面

当实现路线第一步成功时,串口调试助手显示接收到的数据如图4所示,其中除了第一位为0x0f和最后一位为标志位外,其余位的数据由使用相应的遥控器设备助手自定义,即除了第一位和最后一位外,其余位的数值可不必与图4中显示的相同。

c2997ce94ddf4e319bd502ab147c5a16.jpeg

图4:串口调试助手页面

当串口调试助手在配置好相关通信参数的前提下显示的数据没有规律即乱码时,考虑两个可能存在的问题:(1)硬件取反电路搭错了(2)硬件取反电路的供电问题。

2.2、实现路线第二段

        实现路线第二段相比于第一段需要多一个STM32单片机,具体为STM32F103C8T6最小系统板,如图5所示,并且一起配合使用的是一个OLED屏,OLED屏的驱动函数参考B站“江协电子——江科大STM32教程”中的OLED库函数(此处为我母校学长疯狂打call)

91d24d44ece3415a89c085bf16c1af6b.jpeg

图5:STM32最小系统板

这一段的接线为:由于在实现路线第一段中将接收机上的5V电源的正负极分别与USB转串口模块的5V和GND连接了,所以首先将接收机的5V电源线的正负极与USB转串口模块的5V和GND断开,然后将接收机上5V电源正极与ST-Link上的5V引脚连接,接收机上5V电源负极与STM32最小系统板上的GND引脚连接(必须要这样连接,因为sBus协议本质上是UART协议,USART/UART接线要求中要求数据的发送端要与接收端“共地”),然后将搭载了 经取反电路转换后的sBus数据 的信号线 与STM32最小系统板上用于USART通信的Rx引脚即负责串口数据接收的引脚连接(图5中为与PA10连接)。STM32的程序为:

main函数(包含了实现路线第三步中的CAN通信部分)

#include "stm32f10x.h"
#include "usart_RS.h"
#include "OLED.h"
#include "CAN_test.h"
#include "Delay.h"

int main(void)
{	
	usart_RS_Init();
	
		CAN_Config();
	
	CanTxMsg CAN_TxMessage;
	
	//SendString(USART1,"This is a USART receive and send test!");
    OLED_Init();	
	uint16_t* CH_main;
	uint8_t* buf_main;
    while(1)
	{		
		if(Get_flag_CH_deal_finish() == 1)
		{
			CH_main = Get_CH();
			buf_main = Get_buf();
			//OLED_Clear();
			
			CAN_TxMessage.ExtId = 0x1314;
	        CAN_TxMessage.DLC = 8;
	        CAN_TxMessage.IDE = CAN_ID_EXT;
	        CAN_TxMessage.RTR = CAN_RTR_DATA;
	        CAN_TxMessage.Data[0] = CH_main[0];
	        CAN_TxMessage.Data[1] = CH_main[1];
	        CAN_TxMessage.Data[2] = CH_main[2];
	        CAN_TxMessage.Data[3] = CH_main[3];
	        CAN_TxMessage.Data[4] = CH_main[4];
	        CAN_TxMessage.Data[5] = CH_main[5];
	        CAN_TxMessage.Data[6] = CH_main[6];
	        CAN_TxMessage.Data[7] = CH_main[7];
			
//			OLED_ShowNum(1,1,CH_main[0],4);
//			OLED_ShowNum(1,6,CH_main[1],4);
//			OLED_ShowNum(1,11,CH_main[2],4);
//			OLED_ShowNum(2,1,CH_main[3],4);
//			OLED_ShowNum(2,6,CH_main[4],4);
//			OLED_ShowNum(2,11,CH_main[5],4);
//			OLED_ShowNum(3,1,CH_main[6],4);
//			OLED_ShowNum(3,6,CH_main[7],4);
//			OLED_ShowNum(3,11,CH_main[8],4);
//			OLED_ShowNum(4,1,CH_main[9],4);
//			OLED_ShowNum(4,6,CH_main[10],4);
			
//		    OLED_ShowHexNum(1,1,buf_main[0],2);
//			OLED_ShowHexNum(1,4,buf_main[1],2);
//            OLED_ShowHexNum(1,7,buf_main[2],2);
//			OLED_ShowHexNum(1,10,buf_main[3],2);
//			OLED_ShowHexNum(1,13,buf_main[4],2);
//			OLED_ShowHexNum(2,1,buf_main[5],2);
//			OLED_ShowHexNum(2,4,buf_main[6],2);
//			OLED_ShowHexNum(2,7,buf_main[7],2);
//			OLED_ShowHexNum(2,10,buf_main[8],2);
//			OLED_ShowHexNum(2,13,buf_main[9],2);
//			OLED_ShowHexNum(3,1,buf_main[10],2);
//			OLED_ShowHexNum(3,4,buf_main[11],2);
//            OLED_ShowHexNum(3,7,buf_main[12],2);
//			OLED_ShowHexNum(3,10,buf_main[13],2);
//			OLED_ShowHexNum(3,13,buf_main[14],2);
//			OLED_ShowHexNum(4,1,buf_main[15],2);
//			OLED_ShowHexNum(4,4,buf_main[16],2);
//			OLED_ShowHexNum(4,7,buf_main[17],2);
//			OLED_ShowHexNum(4,10,buf_main[18],2);
//			OLED_ShowHexNum(4,13,buf_main[19],2);
			
			CAN_Transmit(CAN1,&CAN_TxMessage);
            Delay_ms(10);
			
			USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
		}
	}	
}

usart_RS.h文件代码为:

#ifndef __USART_RS_H
#define __USART_RS_H

void usart_RS_Init(void);
void SendString(USART_TypeDef* USARTx,char* str);

uint8_t Get_flag_CH_deal_finish(void);

uint16_t* Get_CH(void);

uint8_t* Get_buf(void);

#endif

usart_RS.c文件代码为:

#include "stm32f10x.h"                  // Device header

void usart_RS_Init(void)
{
	//1、打开外设(GPIOA、USART1)时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	
	//2、重置外设参数
	USART_DeInit(USART1);
	
	//3、配置GPIO口
	//配置PA9为复用推挽输出模式
	GPIO_InitTypeDef GPIO_InitStructure={0};
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	//配置PA10为浮空输入模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	//4、配置USART
	USART_InitTypeDef USART_InitStructure={0};
	USART_InitStructure.USART_BaudRate = 100000;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_InitStructure.USART_Parity = USART_Parity_Even;
	USART_InitStructure.USART_StopBits = USART_StopBits_2;
	USART_InitStructure.USART_WordLength = USART_WordLength_9b;
	USART_Init(USART1,&USART_InitStructure);
	
	//5、配置NVIC
	NVIC_InitTypeDef NVIC_InitStructure={0};
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	//6、配置中断
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	
	//7、使能串口
	USART_Cmd(USART1,ENABLE);
}

void SendByte(USART_TypeDef* USARTx,uint8_t data)
{
	USART_SendData(USARTx,data);
	while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}
void SendString(USART_TypeDef* USARTx,char* str)
{
	unsigned int k=0;
	while(*(str+k)!='\0')
	{
		SendByte(USARTx,*(str+k));
		k++;
	}
	while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
}


static uint8_t flag_receive_sBus = 0;
void copyANDdeal_data_sBus(uint8_t ucTemp);
void USART1_IRQHandler(void)
{
	uint8_t ucTemp;
	if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET)
	{
		ucTemp = USART_ReceiveData(USART1);
		if (flag_receive_sBus == 1)
		{
			copyANDdeal_data_sBus(ucTemp);
		}
		else if(ucTemp == 0x0f)
		{
			flag_receive_sBus = 1;
		}
	}
}


static uint8_t buf[24];
static uint8_t count = 0;
static uint16_t CH[10];
static uint8_t flag_CH_deal_finish=0;
void copyANDdeal_data_sBus(uint8_t ucTemp)
{ 
    buf[count] = ucTemp;
    count++;
    if(count == 24)
	{
		CH[ 0] = ((int16_t)buf[ 0] >> 0 | ((int16_t)buf[ 1] << 8 )) & 0x07FF;
        CH[ 1] = ((int16_t)buf[ 1] >> 3 | ((int16_t)buf[ 2] << 5 )) & 0x07FF;
        CH[ 2] = ((int16_t)buf[ 2] >> 6 | ((int16_t)buf[ 3] << 2 )  | (int16_t)buf[ 4] << 10 ) & 0x07FF;
        CH[ 3] = ((int16_t)buf[ 4] >> 1 | ((int16_t)buf[ 5] << 7 )) & 0x07FF;
        CH[ 4] = ((int16_t)buf[ 5] >> 4 | ((int16_t)buf[ 6] << 4 )) & 0x07FF;
        CH[ 5] = ((int16_t)buf[ 6] >> 7 | ((int16_t)buf[ 7] << 1 )  | (int16_t)buf[8] <<  9 ) & 0x07FF;
        CH[ 6] = ((int16_t)buf[ 8] >> 2 | ((int16_t)buf[ 9] << 6 )) & 0x07FF;
        CH[ 7] = ((int16_t)buf[ 9] >> 5 | ((int16_t)buf[10] << 3 )) & 0x07FF; 
        CH[ 8] = ((int16_t)buf[11] << 0 | ((int16_t)buf[12] << 8 )) & 0x07FF;
        CH[ 9] = ((int16_t)buf[12] >> 3 | ((int16_t)buf[13] << 5 )) & 0x07FF;
		
		flag_CH_deal_finish = 1;
		count = 0;
		flag_receive_sBus = 0;
		USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);
	}		
}

uint8_t Get_flag_CH_deal_finish(void)
{
	return flag_CH_deal_finish;
}

uint16_t* Get_CH(void)
{
	flag_CH_deal_finish = 0;
	return CH;
}

uint8_t* Get_buf(void)
{
	flag_CH_deal_finish = 0;
	return buf;
}

关于代码需要注意的事项为:(1)USART通信参数的配置如图6所示,(2)在中断服务子函数中的(void copyANDdeal_data_sBus(uint8_t ucTemp))函数中有一个关闭串口接收中断的函数和在主函数末尾有一个打开串口接收中断的函数。由于接收机是一直向外发送sBus数据,如果没有这两个函数,STM32的主函数会一直被串口接收中断 中断执行。

6f09e6e177c64876aa84d61d959a3aa8.png

图6:USART通信参数的配置 

        检验实现路线第二段是否成功的操作为:可在主函数中写一个“OLED_Clear()”观察OLED屏的刷新频率是否固定,刷新频率不固定即为一会儿刷新快一点,一会儿刷新慢一点。至于为什么可以这样检测的原因为:由于sBus数据段长度固定为25个字节,按照程序逻辑,每接收到24个字节(在上述程序中包头0x0f没有存储,所以是24个字节)并完成解析后会执行一次刷新OLED屏的操作,当接收到的数据不正确时,出现包头即数据0x0f的时间不固定(因为数据不正确的话数据为乱码),那么刷新OLED屏的时间也不固定,时而快时而慢。

        关于实现路线第二段中OLED屏的现象有三种:(1)OLED屏不显示;(2)OLED屏显示数据,在加上OLED屏刷新函数后刷新频率不固定,显示的数据没有规律即乱码;(3)OLED屏显示数据,在加上OLED屏刷新函数后刷新频率固定,显示的数据每一组都在变化但有规律。当出现第一种情况时为串口中断服务子程序中(void copyANDdeal_data_sBus(uint8_t ucTemp))函数的串口接收数据中断未关闭导致的,由于主函数的运行一直被中断服务子函数打断,导致即使接收到数据也没办法显示在OLED屏上,需要注意的是在中断服务子函数中关闭中断后需要在合适的地方打开(上述程序中为在主函数的末尾打开);当出现第二种情况时为STM32接收到的数据有误所致,在实现路线第一段成功的情况下(即由取反电路输出的数据正确的情况下),检查接收机的5V电源GND是否与最小系统板上的GND连接,接收机5V电源的正极是否与ST-Link的5V引脚连接,当不满足USART通信数据发送端与接收端“共地”的要求时,数据接收端接收到的数据可能会存在问题;当出现上述第三种情况时为正常情况,至于显示的数据呈现有规律的变化猜测是OLED的驱动函数问题,可不用管。

2.3、实现路线第三段

        实现路线第三段为将由实现路线第二段中处理后的通道数据CH[ ii ]( ii = 0、1、2...9)赋值给CAN的数据段并通过CAN总线发送出去,具体程序为(下述程序包含CAN接收数据的功能):

CAN_test.h文件代码为:

#ifndef __CAN_test_H
#define __CAN_test_H

void CAN_Config(void);

uint8_t CAN_Get_Flag_Receive(void);

CanRxMsg CAN_Get_RxMessage(void);

#endif

CAN_test.c文件的代码为:

#include "stm32f10x.h"                  // Device header

void CAN_Config(void)
{
	//1、配置(PA11)、(PA12)和CAN1对应的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE);
	
	//2、配置GPIO口
	GPIO_InitTypeDef GPIO_InitStructure={0};
	//配置PA11(CAN_Rx)为上拉输入模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	//配置PA12(CAN_Tx)为复用推挽输出模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	//3、配置CAN模式
	CAN_InitTypeDef CAN_InitStructure={0};      
	CAN_InitStructure.CAN_ABOM = ENABLE;             //自动离线功能
	CAN_InitStructure.CAN_AWUM = ENABLE;             //自动唤醒功能
	CAN_InitStructure.CAN_BS1 = CAN_BS1_5tq;         //配置BS1段长度
	CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;         //配置BS2段长度
	CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;  //配置CAN工作模式
	CAN_InitStructure.CAN_NART = DISABLE;            //配置自动重传功能
	CAN_InitStructure.CAN_Prescaler = 4;             //配置CAN外设的时钟分频
	CAN_InitStructure.CAN_RFLM = DISABLE;            //锁存FIFO
	CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;         //SJW极限值
	CAN_InitStructure.CAN_TTCM = DISABLE;            //是否使能时间触发功能
	CAN_InitStructure.CAN_TXFP = DISABLE;            //配置报文优先级的判别方法
	CAN_Init(CAN1,&CAN_InitStructure);    
	
	//4、配置CAN筛选器参数
	CAN_FilterInitTypeDef CAN_FilterInitStructure={0};
	CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;                //是否使能本筛选器 
	CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FilterFIFO0;   //设置经筛选器筛选后的数据存到哪个FIFO中
    //筛选器中要筛选ID的高16位
	CAN_FilterInitStructure.CAN_FilterIdHigh = ((((u32)0x2023<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF0000)>>16; 
    //筛选器中要筛选ID的低16位
	CAN_FilterInitStructure.CAN_FilterIdLow = (((u32)0x2023<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;               
	CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0xFFFF;               //筛选器中筛选屏蔽位的高16位(设置1的位表示接收报ID的该位必须与筛选器中设置的ID的对应位一致)
	CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0xFFFF;                //筛选器中筛选屏蔽位的低16位(同上)
	CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;      //筛选器的工作模式(列表还是屏蔽模式)
	CAN_FilterInitStructure.CAN_FilterNumber = 0;                        //筛选器组的编号
	CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;     //设置筛选器的长度
	CAN_FilterInit(&CAN_FilterInitStructure);
	
	//5、配置NVIC
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	NVIC_InitTypeDef NVIC_InitStructure={0};
	NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_Init(&NVIC_InitStructure);
	
	//6、使能CAN1的接收中断
	CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);
}

static uint8_t flag_receive=0;
CanRxMsg RxMessage;

void USB_LP_CAN1_RX0_IRQHandler(void)
{
	CAN_Receive(CAN1,CAN_FIFO0,&RxMessage);   //其中CAN_FIFO0与CAN筛选器是设置的关联FIFO相对应
	flag_receive = 1;
	if((RxMessage.ExtId == 0x2023) && (RxMessage.IDE == CAN_ID_EXT) && (RxMessage.DLC == 8))
	{
		flag_receive = 2;
	}
	else
	{
		flag_receive = 3;
	}
}

uint8_t CAN_Get_Flag_Receive(void)
{
	return flag_receive;
}
CanRxMsg CAN_Get_RxMessage(void)
{
	return RxMessage;
}

3、关于共地问题的注意事项

3.1、当使用外部的5V直流电源给接收机供电时

        外部5V电源的GND与STM32最小系统板的GND电平不一致,实际情况如图7、图8所示:

a18b95e749894d58a7db3ccb775aeb1a.jpeg

图7:万用表笔头与外部电源的负极和STM32最小系统板GND连接情况

c7ec8842bafe460688ff5e5fd378d478.jpeg

图8:外部电源负极与STM32最小系统板GND间的电压结果

此时不能满足USART/UART协议中关于数据发送端与接收端“共地”的要求,当由该外部电源给接收机供电时,其sBus信号输出端经取反电路后数据波形如图9、图10所示:

51d781ac8421407291b3976d358a659b.jpeg

图9:当不满足“共地”要求时经取反电路取反后的信号

899739f55b90461c998a4d2ac5de485c.jpeg

图10:对图9进行局部放大后的信号波形

而正常的波形如图11、图12所示:

6eaba09f4e2c4a3bb2682efa47ca0720.jpeg

图11: 满足“共地”要求时信号波形

3cc520fa5ed44781ae86af77532f9777.jpeg

图12:图11进行局部放大后的波形

3.2、外部电源负极与STM32最小系统板间的电位差

        关于外部电源负极与STM32最小系统板GND间的电位差如图13所示:

138085435f2341449c80e50fc22314c8.jpeg

图13:外部电源负极与STM32最小系统板GND端的电位差 

4、结语

        nnd,写了五个小时终于写完了!!!

        我去干饭了,下次有好玩的再写!

 

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目录 0.前言 1 1.课程设计的目的和要求 2 1.1.课程设计的目的 2 1.2.课程设计要求 2 2.总体设计 3 2.1.系统框图 3 2.2.设计原理 4 3.硬件设计 5 3.1.芯片介绍 5 3.2.相应的命令控制字格式 9 3.3.硬件连接图 10 4.软件设计 10 4.1.程序框图 10 4.2.程序清单 14 5.实验数据 14 5.1.0通道数据分析表 14 5.2.程序运行图 14 6.结束语 14 7.参考文献 15 附录一:硬件图连接 16 附录二:程序清单 17 附录三:程序运行图 22 单片机数据采集控制系统 0.前言 单片机的应用简介 单片机是一种集成在电路芯片,是采用超大规模集成电路技术把具有数据处理能力的 中央处理器CPU随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计时器 等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路 )集成到一块硅片上构成的一个小而完善的计算机系统。 目前单片机渗透到我们生活的各个领域,几乎很难找到哪个领域没有单片机的踪迹。 导弹的导航装置,飞机上各种仪表的控制,计算机的网络通讯与数据传输,工业自动化 过程的实时控制和数据处理,广泛使用的各种智能IC卡,民用豪华轿车的安全保障系统 ,录像机、摄像机、全自动洗衣机的控制,以及程控玩具、电子宠物等等,这些都离不 开单片机。更不用说自动控制领域的机器人、智能仪表、医疗器械以及各种智能机械了 。因此,单片机的学习、开发与应用将造就一批计算机应用与智能化控制的科学家、工 程师。   单片机广泛应用于仪器仪表、家用电器、医用设备、航空航天、专用设备的智能化 管理及过程控制等领域,大致可分如下几个范畴:   (1).在智能仪器仪表上的应用   单片机具有体积小、功耗低、控制功能强、扩展灵活、微型化和使用方便等优点, 广泛应用于仪器仪表中,结合不同类型的传感器,可实现诸如电压、功率、频率、湿度 、温度、流量、速度、厚度、角度、长度、硬度、元素、压力等物理量的测量。采用单 片机控制使得仪器仪表数字化、智能化、微型化,且功能比起采用电子或数字电路更加 强大。例如精密的测量设备(功率计,示波器,各种分析仪)。   (2).在工业控制中的应用   用单片机可以构成形式多样的控制系统、数据采集系统。例如工厂流水线的智能化 管理,电梯智能化控制、各种报警系统,与计算机联网构成二级控制系统等。   (3).在家用电器中的应用   可以这样说,现在的家用电器基本上都采用了单片机控制,从电饭煲、洗衣机、电 冰箱、空调机、彩电、其他音响视频器材、再到电子秤量设备,五花八门,无所不在。   (4).在计算机网络和通信领域中的应用   现代的单片机普遍具备通信接口,可以很方便地与计算机进行数据通信,为在计算 机网络和通信设备间的应用提供了极好的物质条件,现在的通信设备基本上都实现了单 片机智能控制,从手机,电话机、小型程控交换机、楼宇自动通信呼叫系统、列车无线 通信、再到日常工作中随处可见的移动电话,集群移动通信,无线电对讲机等。   (5).单片机在医用设备领域中的应用   单片机在医用设备中的用途亦相当广泛,例如医用呼吸机,各种分析仪,监护仪, 超声诊断设备及病床呼叫系统等等。   (6).在各种大型电器中的模块化应用   某些专用单片机设计用于实现特定功能,从而在各种电路中进行模块化应用,而不 要求使用人员了解其内部结构。如音乐集成单片机,看似简单的功能,微缩在纯电子芯 片中(有别于磁带机的原理),就需要复杂的类似于计算机的原理。如:音乐信号以数 字的形式存于存储器中(类似于ROM),由微控制器读出,转化为模拟音乐电信号(类似 于声卡)。   在大型电路中,这种模块化应用极大地缩小了体积,简化了电路,降低了损坏、错 误率,也方便于更换。   (7).单片机在汽车设备领域中的应用   单片机在汽车电子中的应用非常广泛,例如汽车中的发动机控制器,基于CAN总线的 汽车发动机智能电子控制器,GPS导航系统,abs防抱死系统,制动系统等等。   此外,单片机在工商,金融,科研、教育,国防航空航天等领域都有着十分广泛的 用途。 1.课程设计的目的和要求 1.1.课程设计的目的 运用单片机原理及其应用等课程知识,根据题目要求进行软硬件系统的设计和调试,从 而加深对本课程知识的理解, 把学过的比较零碎的知识系统化,比较系统的学习开发单片机应用系统的基本步骤和基 本方法,使学生应用知识能力、设计能力、调试能力以及报告撰写能力等有一定的提高 。 1.2.课程设计要求 用8051单片机设计数据采集控制系统,基本要求如下: 1. 可实现8路数据的采集,假设8路信号均为0-5V的电压信号; 2. 采集数据可通过数码管显
CAN232P型 世界唯一USB/RS-232/RS-485/422通用的 通用串口/CAN转换器 波仕CAN232P型通用串口/CAN转换器秉承波仕转换器的一贯特色:具有超小型的外形(80*23*47mm),USB/RS-232/RS-485/RS-422通用,其中USB虚拟成为本地COM串口。使用USB口时无需供电,而且是用串口通信程序来实现复杂的CAN协议通信。 波仕CAN232P是世界上最小的、也是使用最简便的通用串口/CAN转换器、实现了USB、RS-232、RS-485、RS-422与CAN协议的透明转换。产品本身自己带通信设置功能。CAN232P是波仕新一代专利产品,谨防假冒!专利号:201120197328、200630307752。 CAN232P 通用串口/CAN转换器 通用USB/RS-232/485/422转CAN协议 USB供电、光电隔离 波仕通用串口/CAN转换器实现 USB/RS-232/RS-485/RS-422与CAN协议的透明转换、透明带标识转换。其中USB口可接计算机供电并且转换为虚拟串口,也可接USB电源仅仅用于供电。产品采用高性能低功耗通信芯片,内置高性能微处理器,具有抗干扰性强,通信稳定的特点,可广泛应用于各种场合的CAN-串口通信和工业控制领域。产品本身可将自己的USB口或串口接到计算机后用配置程序进行串口和CAN的通信格式设定,然后用串口通信程序实现CAN协议的通信。 硬件安装 将CAN232P型串口/CAN转换器通过配套的USB延长线(A型USB口到A型USB口)外插到配套电源的USB口或者计算机的USB口。外插计算机USB口时既可以供电,也生成USB虚拟串口。 波仕CAN232P产品的RS-232/485/422串口端是一个DB-9针座,具有RS-232、RS-485、RS-422全部引脚。当作为RS-232口时与PC机的DB-9针RS-232口的2、3、5脚分配完全相同。作为RS-422时,T+、T—是指从CAN232P向外发送。注意RS-485和RS-422通信时建议要接地线(5脚)。RS-485/422无须跳线选择。RS-485/422信号的参考地线与RS-232的GND是一样的。当CAN232P的USB口接到计算机,并且用计算机的USB虚拟串口通信时是不需要电源的。 DB-9针(公)端的引脚分配如下: 1 2 3 4 5 6 7 8 9 RS-232 RXD TXD GND RS-485 A GND B RS-422 T+ GND R+ R— T— 用于设置参数时需要用导线将端子板上的R+接GND(6脚与5脚短接),设置完毕后断开导线并且重新加电源。 性能 串行接口 USB/RS-232/RS-485/422 尺寸及重量 80*23*47mm、90克 串口波特率 1200~115200bps 传输速率 最高每秒400帧 CAN速率 5K~1000K 供电电压 5V (±0.5V) 隔离电压 2500V 电源插座 标准USB座(同计算机的) 工作温度 -40~85?C 功耗 <150mA

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值