BSP模块训练题详解及解析

1.串口1收发

        本题需要使用串口1与PC机进行通信。定义串口1数据的接收区与发送区,数据包匹配头部。初始化串口波特率为2400,设置串口的接收区和数据包头。设置回调函数,若串口1接收到数据包,则将接收到的数据倒序发送回计算机。

#include "STC15F2K60S2.H"        //必须。
#include "sys.H"                 //必须。
#include "uart1.h" 

code unsigned long SysClock=11059200;         //必须。定义系统工作时钟频率(Hz),用户必须修改成与实际工作频率(下载时选择的)一致
#ifdef _displayer_H_                          //显示模块选用时必须。(数码管显示译码表,用戶可修改、增加等) 
code char decode_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x08,0x40,0x01,0x41,0x48,0x76,0x38,0x40,0x00,	
	              /* 序号:   0   	1    2	   3    4	    5    6	  7   8	   	9	 		10	11	 12   13   14   15    16   17   18   19	 */
                /* 显示:   0   	1    2     3    4     5    6    7   8    9  (无)   下-  中-  上-  上中-  中下-  H    L    - 	(无)*/  
	                       0x3f|0x80,0x06|0x80,0x5b|0x80,0x4f|0x80,0x66|0x80,0x6d|0x80,0x7d|0x80,0x07|0x80,0x7f|0x80,0x6f|0x80 };  
             /* 带小数点     20         21         22         23      24        25        26        27        28        29        */
#endif

char rxd[10];
char buffer[10];
char matchhead[2]={0xaa,0x55};

void uart1rxd_callback();

void main() 
{ 	
	//串口初始化
	Uart1Init(2400);
	SetUart1Rxd(rxd, 10, matchhead, 2);
	SetEventCallBack(enumEventUart1Rxd, uart1rxd_callback);
  	MySTC_Init();	    
	while(1)             	
	{
		MySTC_OS();    
	}	             
}                 

void uart1rxd_callback(){
	int i;
	for(i=9;i>=0;i--){
		buffer[i] = rxd[9-i];
	}
	Uart1Print(buffer, 10);
	return;
}

2.串口2通信

        两板使用RS485作为串口2进行通信,使用按键模块控制发送,显示模块将结果显示在LED。对串口2设置5字节的数据接收区和2字节的数据包头,波特率为1200。设置两个回调函数,按下Key1则通过串口2发送定义好的数据,串口2若接收到数据包则将数据求累加和通过led显示。

#include "STC15F2K60S2.H"        //必须。
#include "sys.H"                 //必须。
#include "displayer.h"
#include "key.h"
#include "Uart2.h"

code unsigned long SysClock=11059200;         //必须。定义系统工作时钟频率(Hz),用户必须修改成与实际工作频率(下载时选择的)一致
#ifdef _displayer_H_                          //显示模块选用时必须。(数码管显示译码表,用戶可修改、增加等) 
code char decode_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x08,0x40,0x01,0x41,0x48,0x76,0x38,0x40,0x00,	
	              /* 序号:   0   	1    2	   3    4	    5    6	  7   8	   	9	 		10	11	 12   13   14   15    16   17   18   19	 */
                /* 显示:   0   	1    2     3    4     5    6    7   8    9  (无)   下-  中-  上-  上中-  中下-  H    L    - 	(无)*/  
	                       0x3f|0x80,0x06|0x80,0x5b|0x80,0x4f|0x80,0x66|0x80,0x6d|0x80,0x7d|0x80,0x07|0x80,0x7f|0x80,0x6f|0x80 };  
             /* 带小数点     20         21         22         23      24        25        26        27        28        29        */
#endif

unsigned char rxd[5];
unsigned char buffer[5] = {0xaa,0x55,0x01,0x01,0x01};
unsigned char matchhead[2]={0xaa,0x55};

void uart2rxd_callback();
void key_callback();

void main() 
{ 	
	//初始化
	KeyInit();
	DisplayerInit();
	SetDisplayerArea(0,7);
	Seg7Print(10,10,10,10,10,10,10,10);
	Uart2Init(1200,Uart2Usedfor485);
	SetUart2Rxd(rxd, 5, matchhead, 2);
	//设置回调
	SetEventCallBack(enumEventUart2Rxd,uart2rxd_callback);
	SetEventCallBack(enumEventKey,key_callback);
  	MySTC_Init();	    
	while(1)             	
	{
		MySTC_OS();    
	}	             
}        

void uart2rxd_callback(){
	unsigned char sum = 0x00;
	int i;
	for(i=0;i<5;i++){
		sum+=rxd[i];
	}
	LedPrint(sum);
}

void key_callback(){
	if(GetKeyAct(enumKey1)==enumKeyPress)
		Uart2Print(buffer, 5);
}

3.红外无线通信

#include "STC15F2K60S2.H"        //必须。
#include "sys.H"                 //必须。
#include "displayer.h"
#include "key.h"
#include "IR.h"

code unsigned long SysClock=11059200;         //必须。定义系统工作时钟频率(Hz),用户必须修改成与实际工作频率(下载时选择的)一致
#ifdef _displayer_H_                          //显示模块选用时必须。(数码管显示译码表,用戶可修改、增加等) 
code char decode_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x08,0x40,0x01,0x41,0x48,0x76,0x38,0x40,0x00,	
	              /* 序号:   0   	1    2	   3    4	    5    6	  7   8	   	9	 		10	11	 12   13   14   15    16   17   18   19	 */
                /* 显示:   0   	1    2     3    4     5    6    7   8    9  (无)   下-  中-  上-  上中-  中下-  H    L    - 	(无)*/  
	                       0x3f|0x80,0x06|0x80,0x5b|0x80,0x4f|0x80,0x66|0x80,0x6d|0x80,0x7d|0x80,0x07|0x80,0x7f|0x80,0x6f|0x80 };  
             /* 带小数点     20         21         22         23      24        25        26        27        28        29        */
#endif

unsigned char rxd[5];
unsigned char buffer[5] = {0x01,0x01,0x01,0x01,0x01};

void ir_callback();
void key_callback();

void main() 
{ 	
	//初始化
	KeyInit();
	IrInit(NEC_R05d);
	DisplayerInit();
	SetDisplayerArea(0,7);
	Seg7Print(10,10,10,10,10,10,10,10);
	SetIrRxd(rxd,5);
	//设置回调
	SetEventCallBack(enumEventIrRxd,ir_callback);
	SetEventCallBack(enumEventKey,key_callback);
  	MySTC_Init();	    
	while(1)             	
	{
		MySTC_OS();    
	}	             
}        

void ir_callback(){
	unsigned char sum = 0x00;
	int i;
	for(i=0;i<5;i++){
		sum+=rxd[i];
	}
	LedPrint(sum);
}

void key_callback(){
	if(GetKeyAct(enumKey1)==enumKeyPress)
		IrPrint(buffer, 5);
}

4.实时时钟

        使用实时时钟模块以及显示模块显示时间。定义一个实时时钟数据结构用于校准时钟。写RTC校准时间,设置回调函数读取RTC时间并更新显示在数码管,显示时注意RTC值为BCD码。

//******* 用户程序段1:用户程序包含文件 *************
#include "STC15F2K60S2.H"        //必须。
#include "sys.H"                 //必须。
#include "displayer.H" 
#include "DS1302.h"
code unsigned long SysClock=11059200;         //必须。定义系统工作时钟频率(Hz),用户必须修改成与实际工作频率(下载时选择的)一致
#ifdef _displayer_H_                          //显示模块选用时必须。(数码管显示译码表,用戶可修改、增加等) 
code char decode_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x08,0x40,0x01, 0x41, 0x48, 
	              /* 序号:   0   1    2	   3    4	    5    6	  7   8	   9	 10	   11		12   13    14     15     */
                /* 显示:   0   1    2    3    4     5    6    7   8    9  (无)   下-  中-  上-  上中-  中下-   */  
	                       0x3f|0x80,0x06|0x80,0x5b|0x80,0x4f|0x80,0x66|0x80,0x6d|0x80,0x7d|0x80,0x07|0x80,0x7f|0x80,0x6f|0x80 };  
             /* 带小数点     0         1         2         3         4         5         6         7         8         9        */
#endif
unsigned char x[45];
float a,b,c,d;

struct_DS1302_RTC time={0x30,0,3,22,8,1,0x22}; 
struct_DS1302_RTC tmp; 
void my1mS_callback()				               
{ 	
	tmp=RTC_Read();
	Seg7Print(tmp.hour/16,tmp.hour%16,12,tmp.minute/16,tmp.minute%16,12,tmp.second/16,tmp.second%16);
}


void main() {         
	DisplayerInit();
	SetDisplayerArea(0,7);
	Seg7Print(10,10,10,10,10,10,10,10);
	DS1302Init(time);
	RTC_Write(time);
	SetEventCallBack(enumEventSys1mS, my1mS_callback);           
	MySTC_Init();	       
	while(1){ 
			MySTC_OS();    			
		}	              
}   

从下题起代码没有贴头文件和数码管的decode_table。

5.非易失存储

        使用M24C02模块存储数据。读出地址0x01的值并+1,再写回地址0x01,并将该值通过led显示。

void main() 
{ 	
	unsigned char x;
	DisplayerInit();
	x = M24C02_Read(0x01) + 1;
	M24C02_Write(0x01, x);
	SetDisplayerArea(0,7);
	Seg7Print(10,10,10,10,10,10,10,10); 
	LedPrint(x);
  	MySTC_Init();	    
	while(1)             	
	{
		MySTC_OS();    
	}	             
}  

6.收音机

        使用收音机模块。初始化后定义一个收音机参数结构设置参数为91.8MHz,音量6。

void main() 
{ 	
	struct_FMRadio radio = {918,6,1,0,0};
	FMRadioInit(radio);
  	MySTC_Init();	    
	while(1)             	
	{
		MySTC_OS();    
	}	             
} 

7.音乐播放器

        使用音乐模块进行播放。定义一段音乐编码,每个发音编码成对出现,音高1字节,节拍1字节。对蜂鸣器和音乐模块初始化,设置音乐编码的位置,音调与bpm,然后开始播放。

code unsigned char song[]={0x21,0x10,0x21,0x10,0x25,0x10,0x25,0x10,0x26,0x10,0x26,0x10,0x25,0x10};
void main() 
{   
	BeepInit();
	MusicPlayerInit();
	SetMusic(90,0xFA,&song,sizeof(song),enumMscNull);
	SetPlayerMode(enumModePlay);
  	MySTC_Init();	    
	while(1)             	
		{ 
			MySTC_OS();    
		}	             
}    

8.温度值计算

        温度值的获取和显示需要使用显示模块和模数转换模块。根据参考资料中的温度/光照测量,通过GetADC()获取10位ad值并将其转换为8位ad值,取多次值求平均值减小误差,并将这个平均值显示在数码管上。设定两个回调函数,一个每1ms取一次ad值,取200个值后求均值并查表更新温度结果。另一个回调函数每1s更新一次数码管显示的温度值。

unsigned int adc_10bit = 0;			//热敏电阻adc 10bit
unsigned long sumt = 0;				//求和
unsigned int data_temp = 0;			//四舍五入的均值
unsigned int t = 0;					//计数
unsigned int flag;					//符号位
int temp = 0;
struct_ADC adc_data;						
//温度值对应表
int code tempdata[]={239,197,175,160,150,142,135,129,124,120,116,113,109,107,104,101, 
										  99, 97, 95, 93, 91, 90, 88, 86, 85, 84, 82, 81, 80, 78, 77, 76, 
										  75, 74, 73, 72, 71, 70, 69, 68, 67, 67, 66, 65, 64, 63, 63, 62, 
										  61, 61, 60, 59, 58, 58, 57, 57, 56, 55, 55, 54, 54, 53, 52, 52, 
										  51, 51, 50, 50, 49, 49, 48, 48, 47, 47, 46, 46, 45, 45, 44, 44, 
										  43, 43, 42, 42, 41, 41, 41, 40, 40, 39, 39, 38, 38, 38, 37, 37, 
										  36, 36, 36, 35, 35, 34, 34, 34, 33, 33, 32, 32, 32, 31, 31, 31, 
										  30, 30, 29, 29, 29, 28, 28, 28, 27, 27, 27, 26, 26, 26, 25, 25,
										  24, 24, 24, 23, 23, 23, 22, 22, 22, 21, 21, 21, 20, 20, 20, 19, 
										  19, 19, 18, 18, 18, 17, 17, 16, 16, 16, 15, 15, 15, 14, 14, 14, 
										  13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 10, 9, 9, 9, 8, 8, 8, 7, 
										  7, 7, 6, 6,5, 5, 54,4, 3, 3,3, 2, 2, 1, 1, 1, 0, 0, -1, -1, -1, 
										  -2, -2, -3, -3, -4, -4, -5, -5, -6, -6, -7, -7, -8, -8, -9, -9, 
										  -10, -10, -11, -11, -12, -13, -13, -14, -14, -15, -16, -16, -17, 
										  -18, -19, -19, -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, 
										  -30, -32, -33, -35, -36, -38, -40, -43, -46, -50, -55, -63, 361};

//1s更新一次温度值
void displayer1s_callback(){
	Seg7Print(10,10,10,10,10,flag,temp/10,temp%10);
}
//取多个值求均值
void adc1ms_callback(){
	t++;
	if(t==200){
			data_temp=(sumt+t/2)/t;					//四舍五入
			temp=tempdata[data_temp-1]; 			//查找对应的AD的温度值
			if(temp<0){
				flag = 12;							//若温度为负,显示负号
			}
			else{
				flag = 0;
			}
			sumt=0;
			t=0;
	}
	adc_data = GetADC();
	adc_10bit = adc_data.Rt;
	data_temp=adc_10bit>>2;							//由10位AD值转换为8位AD值
	sumt+=data_temp;								//求t次AD值的和
}

void main() 
{ 	
	DisplayerInit();
	SetDisplayerArea(0,7);	
	AdcInit(ADCexpEXT);
	SetEventCallBack(enumEventSys1mS,adc1ms_callback);
	SetEventCallBack(enumEventSys1S,displayer1s_callback);
  	MySTC_Init();	    
	while(1)             	
	{
		MySTC_OS();    
	}	             
} 

9.扩展模板

        使用EXT模块和显示模块。初始化ext接口功能为超声波测距,设置回调函数,每1s更新一次超声波测距的值。

void ext_callback(){
	int dis = GetUltraSonic(); 
	Seg7Print(10,10,10,10,10,10,dis/10,dis%10);
}

void main() 
{ 	
	EXTInit(enumEXTUltraSonic);
	displayerInit();
	SetDisplayerArea(0,7);
	SetEventCallBack(enumEventSys1S,ext_callback);
  MySTC_Init();	    
	while(1)             	
	{
		MySTC_OS();    
	}	             
}     

10.直流电机

        使用电机模块和按键模块。按下按键1,2控制电机正转,反转。正转时速度为50%。反转时速度为30%。

void key_callback(){
	if(GetKeyAct(enumKey1)==enumKeyPress){
		SetPWM(50, 10, 0, 0);
	}
	else if(GetKeyAct(enumKey2)==enumKeyPress){
		SetPWM(0, 0, 30, 10);
	}
}

void main() 
{ 	
	KeyInit();
	EXTInit(enumEXTPWM );
	SetEventCallBack(enumEventKey,key_callback);
  MySTC_Init();	    
	while(1)             	
	{
		MySTC_OS();    
	}	             
}      

物联沃分享整理
物联沃-IOTWORD物联网 » BSP模块训练题详解及解析

发表评论