本帖最后由 lifangxu 于 2016-12-2 10:53 编辑
第一次申请到NUCLEO的板子,不知道上面外设这么少,不过也适合根据自己需求开发,毕竟价格不高,就打算实验通过GPS模块,接收定位将经纬度显示到SPI驱动OLED上,credic to同事小邱两天的调试,以下为我的整理 其中用到的OLED是中景园电子0.96OLED显示屏,GPS模块用的ublox,编程调试工具是IAR-7.7。
![]()
首先通过 STM32CubeMX 配置 NUCLEO-F412ZG板:
1. SPI片选采用软件方式,调试模式选择SW
2. 时钟配置,由于板子只有RTC晶振所以选择HSI;
3. 外设配置
4. 中断配置
按照以上STM32CubeF4 配置生成工程,然后通过 IAR编程实现,过程为: 接收GPS数据->校验->经纬分转化->显示在OLED上 部分代码:
- int main(void)
- {
- /* MCU Configuration----------------------------------------------------------*/
-
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
- HAL_Init();
-
- /* Configure the system clock */
- SystemClock_Config();
-
- /* Initialize all configured peripherals */
- MX_GPIO_Init();
- MX_SPI1_Init();
- MX_TIM3_Init();
- MX_USART1_UART_Init();
- MX_USART2_UART_Init();
-
- /* USER CODE BEGIN 2 */
- OLED_Init();
- QueueInit(&USART1Recieve);
- HAL_TIM_Base_Start_IT(&htim3);
- if(HAL_UART_Receive_IT(&huart2,aRx2Buffer,1)!=HAL_OK)Error_Handler();
- /* USER CODE END 2 */
-
- /* Infinite loop */
- /* USER CODE BEGIN WHILE */
- while (1)
- {
- Run_Led();
- if(get_GPS_String(&USART1Recieve,GPRMC,&GPRMC_Lens))
- {
- if(GPRMC_Lens < 60)//数据长试不够,肯定没有有效定位
- {
- memset(GPRMC, 0, GPRMC_Lens);
- GPRMC_Lens = 0;//reset
- }
- else
- {
- if((GPS_CheckSum(GPRMC,GPRMC_Lens)) != 0)//校验成功
- {
- GPRMC_DePacking(GPRMC, &GPS_NEED_DATA);
- /*纬度分转化成度*/
- double t_lat = atof((char*)GPS_NEED_DATA.Lat);
- t_lat /= 100;
- double t_lat_point = (t_lat - (int)t_lat)*100/60;
- t_lat = (int)t_lat + t_lat_point;
- sprintf((char*)LAT,"%02.6f",t_lat);
- /*经度分转化成度*/
- double t_lon = atof((char*)GPS_NEED_DATA.Lon);
- t_lon /= 100;
- double t_lon_point = (t_lon - (int)t_lon)*100/60;
- t_lon = (int)t_lon + t_lon_point;
- sprintf((char*)LON,"%03.6f",t_lon);
- /*显示到OLED*/
- //OLED_ShowString(0,0,"LAT:");
- OLED_ShowCHinese(0,0,1);//纬
- OLED_ShowCHinese(18,0,2);//度
- OLED_ShowString(36,0,":");//:
- OLED_ShowString(0,2,LAT);
- //OLED_ShowString(0,4,"LON:");
- OLED_ShowCHinese(0,4,0);//经
- OLED_ShowCHinese(18,4,2);//度
- OLED_ShowString(36,4,":");//:
- OLED_ShowString(0,6,LON);
- memset(GPRMC, 0, GPRMC_Lens);
- GPRMC_Lens = 0;//reset
- }
- else
- {
- memset(GPRMC, 0, GPRMC_Lens);
- GPRMC_Lens = 0;//reset
- }
- }
- }
-
- /* USER CODE END WHILE */
-
- /* USER CODE BEGIN 3 */
-
- }
- /* USER CODE END 3 */
-
- }
复制代码
- //显示2个数字
- //x,y :起点坐标
- //len :数字的位数
- //size:字体大小
- //mode:模式 0,填充模式;1,叠加模式
- //num:数值(0~4294967295);
- void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size2)
- {
- uint8_t t,temp;
- uint8_t enshow=0;
- for(t=0;t
- {
- temp=(num/oled_pow(10,len-t-1))%10;
- if(enshow==0&&t<(len-1))
- {
- if(temp==0)
- {
- OLED_ShowChar(x+(size2/2)*t,y,' ');
- continue;
- }
- else
- enshow=1;
-
- }
- OLED_ShowChar(x+(size2/2)*t,y,temp+'0');
- }
- }
- //显示汉字
- //阴码
- //逆向
- //列行式
- void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no)
- {
- uint8_t t;//,adder=0;
- OLED_Set_Pos(x,y);
- for(t=0;t<16;t++)
- {
- OLED_WR_Byte(LAT_LON[2*no][t],OLED_DATA);
- //adder+=1;
- }
- OLED_Set_Pos(x,y+1);
- for(t=0;t<16;t++)
- {
- OLED_WR_Byte(LAT_LON[2*no+1][t],OLED_DATA);
- //adder+=1;
- }
- }
复制代码
实验效果:
其中字库可以用PCtoLCD2002生成,因为本实验简单只用到了3个汉字,就直接写到程序中了haha~ 不过大型字库还需要存储到FLASH或存储芯片上。
参考资料:
|