STM32与nRF905模块间的电路连好后,剩下的工作就是编写程序了。都说STM32的固件库难用,但俺觉得从中可以学到不少东西,尤其是模块化编程的思想。STM32的固件库将各外设模块的操作独立为一个个的.c和.h代码文件,需要使用哪个外设只需声明包含对应的代码文件即可,非常方便。
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
于是俺也照葫芦画瓢,将无线数传系统软件划分为以下几个模块,各模块分别由一个.c文件和一个.h头文件组成。
1.主程序,main和时钟设置;
2.SPI设置模块,用来SPI端口的设置;
3.USART设置模块,用来设置串口数据格式、波特率等;
4.nRF905模块,用来完成nRF905的设置、数据发送和接收等功能;
下面以刚完成的USART模块为例进行说明:
USART.h文件
/**********************
* USART模块
* Liongt's 实验室制作
* Ver-1.0
* 2008.8
***********************/
#ifndef __USART_H
#define __USART_H
#include "stm32f10x_lib.h"
#include "stdio.h"
#define USE_USART1
//#define USE_USART2
//#define USE_USART3
#ifdef USE_USART1
#define USARTx USART1
#define GPIOx GPIOA
#define RCC_APB2Periph_GPIOx RCC_APB2Periph_GPIOA
#define GPIO_RxPin GPIO_Pin_10
#define GPIO_TxPin GPIO_Pin_9
#elif defined USE_USART2
#define USARTx USART2
#define GPIOx GPIOD
#define RCC_APB2Periph_GPIOx RCC_APB2Periph_GPIOD
#define RCC_APB1Periph_USARTx RCC_APB1Periph_USART2
#define GPIO_RxPin GPIO_Pin_6
#define GPIO_TxPin GPIO_Pin_5
#elif defined USE_USART3
#define USARTx USART3
#define GPIOx GPIOB
#define RCC_APB2Periph_GPIOx RCC_APB2Periph_GPIOB
#define RCC_APB1Periph_USARTx RCC_APB1Periph_USART3
#define GPIO_RxPin GPIO_Pin_11
#define GPIO_TxPin GPIO_Pin_10
#endif
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
void USART_Configuration(void);
#endif /* __USART_H */
USART.c文件
/**********************
* USART模块
* Liongt's 实验室制作
* Ver-1.0
* 2008.8
***********************/
#include "USART.h"
/*******************************************************************************
* Function Name : USART_Configuration(void);
* Description : Configures the USART ports.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void USART_Configuration(void)
{
USART_InitTypeDef USART_InitStructure; //定义串口初始化结构体
GPIO_InitTypeDef GPIO_InitStructure;
//使能串口时钟
#ifdef USE_USART1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
#else
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USARTx, ENABLE);
#endif
//打开GPIO和AFIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOx | RCC_APB2Periph_AFIO, ENABLE);
USART_InitStructure.USART_BaudRate = 115200; //波特率115200
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //8位数据
USART_InitStructure.USART_StopBits = USART_StopBits_1; //1个停止位
USART_InitStructure.USART_Parity = USART_Parity_No ; //无校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //禁用RTSCTS硬件流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //使能接收/发送
USART_InitStructure.USART_Clock = USART_Clock_Disable; //串口时钟禁止
USART_InitStructure.USART_CPOL = USART_CPOL_Low; //时钟下降沿有效
USART_InitStructure.USART_CPHA = USART_CPHA_2Edge; //数据在第二个时钟沿捕捉
USART_InitStructure.USART_LastBit = USART_LastBit_Disable; //最后数据位的时钟脉冲不输出到SCLK引脚
USART_Init(USARTx, &USART_InitStructure); //初始化串口(USARTx在main.h中定义)
USART_Cmd(USARTx, ENABLE); //串口使能
//重映射端口
#ifdef USE_USART2
/* Enable the USART2 Pins Software Remapping */
GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE); //使能GPIO端口映射USART2
#endif
/* Configure USARTx_Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_TxPin;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //引脚频率50M
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //设置Tx引脚为推拉输出模式
GPIO_Init(GPIOx, &GPIO_InitStructure);
/* Configure USARTx_Rx as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_RxPin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //设置Rx引脚为浮点输入模式
GPIO_Init(GPIOx, &GPIO_InitStructure);
}
/*******************************************************************************
* Function Name : PUTCHAR_PROTOTYPE
* Description : Retargets the C library printf function to the USART.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
PUTCHAR_PROTOTYPE
{
/* Write a character to the USART */
USART_SendData(USARTx, (u8) ch);
/* Loop until the end of transmission */
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET)
{
}
return ch;
}
各个USART的I/O和时钟都在USART.h头文件中进行声明,USART的设置函数在USART.c中定义。要使用几号USART,只需在USART.h头文件中用define声明即可,例如:#define USE_USART1。最后在main文件中包含USART.h,调用USART_Configuration()函数完成串口的设置。
俺觉得像这样使用模块化编程的好处是:
1.便于维护:修改错误或新增功能时只需修改相应的模块即可;
2.复用性强:各功能模块与主程序相互独立,只在需要时加载;
3.便于移植:与处理器和编译环境交互的部分都封装在各模块中,使用的处理器和编译环境改变时,只需修改各模块中的相关语句即可。
4.便于分工协作:不同功能的模块可由几个程序员分别完成,之间互不影响。
送给大家的奥运大礼包,别忘了顶啊!
用户305271 2011-6-5 17:39
用户355065 2011-4-12 16:06
dwwzl 2008-9-25 10:37
用户1560991 2008-8-9 15:42
hendiao 2008-8-8 11:57