//==========================STM32不完全手册 C语言复习部分================================//
移位操作提高代码的可读性
移位操作在单片机开发中也非常重要,下面让我们看看固件库的 GPIO 初始化的函数里
面的一行代码
//=====================================================================================//
//0x01=0000 0001(B),左移4位,变为0001 0000; 因为移走后补零,相当于只有1在移动,相当于只把pinpos位设为1
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 了。
//==============================CAN通信代码==================================//
/********************************************************************************
给底盘电调发送指令
*********************************************************************************/
void Set_CM_Speed(CAN_TypeDef *CANx, int16_t cm1_iq, int16_t cm2_iq, int16_t cm3_iq, int16_t cm4_iq)
{
CanTxMsg tx_message;
tx_message.StdId = 0x200;
tx_message.IDE = CAN_Id_Standard;
tx_message.RTR = CAN_RTR_Data;
tx_message.DLC = 0x08;
tx_message.Data[0] = (uint8_t)(cm1_iq >> 8);
tx_message.Data[1] = (uint8_t)cm1_iq;
tx_message.Data[2] = (uint8_t)(cm2_iq >> 8);
tx_message.Data[3] = (uint8_t)cm2_iq;
tx_message.Data[4] = (uint8_t)(cm3_iq >> 8);
tx_message.Data[5] = (uint8_t)cm3_iq;
tx_message.Data[6] = (uint8_t)(cm4_iq >> 8);
tx_message.Data[7] = (uint8_t)cm4_iq;
CAN_Transmit(CANx,&tx_message);
}
代码中cm1_iq为16位变量,而Data[ ]储存8位变量
//假设cm1_iq=12345678 11112222,左移8位(12345678原来位置补零,11112222移没了),变为00000000 12345678
tx_message.Data[0] = (uint8_t)(cm1_iq >> 8);
//u16型变量强制转换为u8型变量,只保留低8位
tx_message.Data[1] = (uint8_t)cm1_iq;
也就是说u16型变量cm1_iq储存到u8型数组Data[ ]中,高8位储存到Data[1]中,底8位储存到Data[2]中
//======================正点原子关于u16转u8的问答===============================//
问题 u8 a; | |
回答2 可以采用强制转换a=(u8)b取低8位,没有警告 |
问答链接:http://www.openedv.com/forum.php?mod=viewthread&tid=233661