1.函数标题及函数命名及函数中的注释
1)函数标题:包括函数名 参数 返回值 函数功能的描述
2)函数命名:最开始的几个字符为文件名(TM7705为文件名),然后看是设备就加Device(TM7705_Device_Init)还是再底层的SPI、IIC等(TM7705_SPI_Init),
再加动宾短语
3)代码注释:代码块的注释用/* xxxxx */ 而代码行的注释用// xxxxx
/* CS引脚设置为低电平 */
#define CLR_TM7705_CS_PIN() GPIO_ResetBits(TM7705_GENERAL_PORT,TM7705_CS_PIN)
/*****************************************************************************************
* @brief TM7705_SPI_Init
* @param void
* @return void
* @note TM7705所用的SPI初始化
******************************************************************************************/
void TM7705_SPI_Init(void)
{
/* TM7705 SPI时钟使能 */
ENABLE_TM7705_SPI_CLK();
}
/*****************************************************************************************
* @brief TM7705_Device_Init
* @param void
* @return void
* @note TM7705所用的SPI初始化
******************************************************************************************/
void TM7705_Device_Init(void)
{
/* TM7705 PORT时钟使能 */
ENABLE_TM7705_PORT_CLK(); // TM7705 PORT时钟使能
/* TM7705 的SPI初始化 */
TM7705_SPI_Init();
}
2.引脚的port pin CLK的命名
/* AD7606所用的GPIO的命名*/
#define AD7606_CONVT_GPIO_PIN GPIO_Pin_2 //PE2
#define AD7606_RESET_GPIO_PIN GPIO_Pin_3 //PE3
#define AD7606_CONVT_GPIO_PORT GPIOE
#define AD7606_RESET_GPIO_PORT GPIOE
#define AD7606_CONVT_GPIO_CLK RCC_APB2Periph_GPIOE
#define AD7606_RESET_GPIO_CLK RCC_APB2Periph_GPIOE
#define ENABLE_AD7606_GENERAL_PORT_CLK() RCC_APB2PeriphClockCmd(AD7606_CONVT_GPIO_CLK | AD7606_CONVT_GPIO_CLK, ENABLE )
3.位操作:
1) 不改变其他位的值的状况下,对某几个位进行设值。
这个场景单片机开发中经常使用,方法就是先对需要设置的位用&操作符进行清零操作,然后用|操作符设值。
比如我要改变 GPIOA 的状态,可以先对寄存器的值进行&清零操作
GPIOA->CRL&=0XFFFFFF0F; //将第4-7位清 0
然后再与需要设置的值进行|或运算
GPIOA->CRL|=0X00000040; //设置相应位的值,不改变其他位的值
2) 移位操作提高代码的可读性。
移位操作在单片机开发中也非常重要,下面让我们看看固件库的 GPIO 初始化的函数里面的一行代码
GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
这个操作就是将 BSRR 寄存器的第 pinpos 位设置为 1,为什么要通过左移而不是直接设置一个固定的值呢?
其实,这是为了提高代码的可读性以及可重用性。这行代码可以很直观明了的知道,是将第 pinpos 位设置为 1。
如果你写成
GPIOx->BSRR =0x0030;
这样的代码就不好看也不好重用了。
类似这样的代码很多:
GPIOA->ODR|=1<<5; //PA.5 输出高,不改变其他位
这样我们一目了然, 5 告诉我们是第 5 位也就是第 6 个端口, 1 告诉我们是设置为 1 了。
3) ~取反操作使用技巧
SR 寄存器的每一位都代表一个状态,某个时刻我们希望去设置某一位的值为 0,同时
其他位都保留为 1,简单的作法是直接给寄存器设置一个值:
TIMx->SR=0xFFF7;
这样的作法设置第 3 位为 0,但是这样的作法同样不好看,并且可读性很差。看看库函数
代码中怎样使用的:
TIMx->SR = (uint16_t)~TIM_FLAG;
而 TIM_FLAG 是通过宏定义定义的值:
#define TIM_FLAG_Update ((uint16_t)0x0001)
#define TIM_FLAG_CC1 ((uint16_t)0x0002)
看这个应该很容易明白,可以直接从宏定义中看出 TIM_FLAG_Update 就是设置的第 0 位了,
可读性非常强
4. ifdef条件编译
单片机程序开发过程中,经常会遇到一种情况, 当满足某条件时对一组语句进行编译,而
当条件不满足时则编译另一组语句。
条件编译命令最常见的形式为:
// #define 标识符
#ifdef 标识符
程序段 1
#else
程序段 2
#endif
5. 用 volatile
关键字声明全局变量,
- 这样编译器就不会把它们保存在寄存器中,保证一致性
补偿ing...........