使用STM32CUBEMX配置
需要使用的有
USART1
USART2
PG15 红外接收
ADC1
FSMC 实现LCD显示
几个LED
不要忘了RCC
配置
主要问题
让STM32自动完成连接AP,建立TCP,打开透传模式
不能一股脑的把这些命令都发过去,得有延时
如果发送时有几个命令没发送成功怎么办
如何解决红外信号接收和传感器数据发送之间的冲突?
在while循环中,传感器数据每循环一次就发一次,太快了,这样会有大量数据都是一样的而没有用处,而且对于温度这样的数据也没有必要,因为温度也变化不那么快,所以最好一段时间发一次
如果使用Delay延时的话,那么在延时期间,要接收红外信号怎么办,延时过后很快再发一次数据,然后又进入延时,这样根本接收不到红外遥控数据啊
这里要理解,发送传感器数据是一个长时间持续的事件,需要在while里面,而且要降低发送的频率
接收红外信号是一个突发事件,相当于一次中断(这里的意思是不是同时处理发送数据和接收数据,不是多线程,单片机没有系统也没法写多线程),接收事件可以发生在延时期间,也可能会发生在发生数据和开始或结束延时之间,
方法一:
Delay是可以重写的,这样的话,在这个函数中进行接收数据的操作,然后结束这个Delay函数就行了,因为这个Delay也是个while循环
HAL_Delay函数
/**
* @brief This function provides minimum delay (in milliseconds) based
* on variable incremented.
* @note In the default implementation , SysTick timer is the source of time base.
* It is used to generate interrupts at regular time intervals where uwTick
* is incremented.
* @note This function is declared as __weak to be overwritten in case of other
* implementations in user file.
* @param Delay: specifies the delay time length, in milliseconds.
* @retval None
*/
__weak void HAL_Delay(__IO uint32_t Delay)
{
uint32_t tickstart = HAL_GetTick();
uint32_t wait = Delay;
/* Add a period to guarantee minimum wait */
if (wait < HAL_MAX_DELAY)
{
wait++;
}
while((HAL_GetTick() - tickstart) < wait)
{
}
}
使用HAL_Delay函数会出现收到两次红外信号后,整个程序会一直处于while循环中,不能接收红外信号,也不能发送温度数据
方法二:
自己写延时函数,不使用systick中断,仿原子延时
void delay_us_while(uint32_t i)
{
uint32_t temp;
SysTick->LOAD=9*i; //ÉèÖÃ֨װÊýÖµ, 72MHZʱ
SysTick->CTRL=0X01; //ʹÄÜ£¬¼õµ½ÁãÊÇÎÞ¶¯×÷£¬²ÉÓÃÍⲿʱÖÓÔ´
SysTick->VAL=0; //ÇåÁã¼ÆÊýÆ÷
do
{
temp=SysTick->CTRL; //¶ÁÈ¡µ±Ç°µ¹¼ÆÊýÖµ
if(UsartType2.RX_flag) // Receive flag
{
UsartType2.RX_flag=0; // clean flag
HAL_UART_Transmit(&huart1, (uint8_t *)messagetocom, sizeof(messagetocom), 0xFFFF);
HAL_UART_Transmit(&huart1, UsartType2.RX_pData, UsartType2.RX_Size, 0xFFFF);
printf("---------------------\n\n");
continue;
}
if(hw_jsbz==1) //Èç¹ûºìÍâ½ÓÊÕµ½
{
hw_jsbz=0; //ÇåÁã
printf("\n ½ÓÊÕµ½ºìÍâÐźţº%0.8X\r\n",hw_jsm); //´òÓ¡
//HAL_UART_Transmit(&huart2, (uint8_t *)&hw_jsm, sizeof(hw_jsm), 0xFFFF);
if(hw_jsm == 0x926D22DD)//1 LED1
{
if(HAL_GPIO_ReadPin(GPIOC,IR_STATUS_Pin)==GPIO_PIN_SET)
{
HAL_GPIO_WritePin(GPIOC,IR_STATUS_Pin,GPIO_PIN_RESET);
}
else
{
HAL_GPIO_WritePin(GPIOC,IR_STATUS_Pin,GPIO_PIN_SET);
}
HAL_UART_Transmit(&huart2, (uint8_t *)hongawai, sizeof(hongawai), 0xFFFF);
continue;
}
else if(hw_jsm == 0x926D629D) //3 LED3
{
HAL_GPIO_TogglePin(GPIOC,ESP_STATUS_Pin);
HAL_UART_Transmit(&huart2, (uint8_t *)hongawai, sizeof(hongawai), 0xFFFF);
continue;
}
else if(hw_jsm == 0x926DAA55) //9
{
HAL_UART_Transmit(&huart2, (uint8_t *)message01, sizeof(message01), 0xFFFF);
LCD_Clear(MAGENTA);
HAL_UART_Transmit(&huart2, (uint8_t *)hongawai, sizeof(hongawai), 0xFFFF);
continue;
}
else if(hw_jsm == 0x926D827D) //6
{
LCD_Clear(GRED);
LCD_DrawRectangle(50,50,100,100);
HAL_UART_Transmit(&huart2, (uint8_t *)hongawai, sizeof(hongawai), 0xFFFF);
continue;
}
else if(hw_jsm == 0x926DE01F) //5
{
LCD_Clear(CYAN);
LCD_DrawFillRectangle(60,60,99,99);
HAL_UART_Transmit(&huart2, (uint8_t *)hongawai, sizeof(hongawai), 0xFFFF);
continue;
}
else if(hw_jsm == 0x926D12ED) //0
{
LCD_Clear(GBLUE);
HAL_UART_Transmit(&huart2, (uint8_t *)hongawai, sizeof(hongawai), 0xFFFF);
continue;
}
hw_jsm=0; //½ÓÊÕÂëÇåÁã
//break;
}
}
while((temp&0x01)&&(!(temp&(1<<16))));//µÈ´ýʱ¼äµ½´ï
SysTick->CTRL=0; //¹Ø±Õ¼ÆÊýÆ÷
SysTick->VAL=0; //Çå¿Õ¼ÆÊýÆ÷
}
这样就解决了一个持续事件和一个突发事件的冲突问题
esp8266配置
http://blog.youkuaiyun.com/superce/article/details/78273652
红外信号获取
配置
注意PG15的配置
GPIO_InitStruct.Pin = GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
要设置为上拉模式,下降沿触发
实现
http://blog.youkuaiyun.com/superce/article/details/77713926
FSMC驱动LCD显示
http://blog.youkuaiyun.com/superce/article/details/77644505
芯片温度使用芯片内部ADC获得
配置
主要代码
/*##-1- Start the conversion process #######################################*/
HAL_ADC_Start(&hadc1);
/*##-2- Wait for the end of conversion #####################################*/
/* Before starting a new conversion, you need to check the current state of
the peripheral; if it’s busy you need to wait for the end of current
conversion before starting a new one.
For simplicity reasons, this example is just waiting till the end of the
conversion, but application may perform other tasks while conversion
operation is ongoing. */
HAL_ADC_PollForConversion(&hadc1, 50);
/* Check if the continous conversion of regular channel is finished */
if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))
{
/*##-3- Get the converted value of regular channel ######################*/
AD_Value = HAL_ADC_GetValue(&hadc1);
// printf("MCU Temperature : %.1f¡æ\n\r",((AD_Value*3300/4096-760)/2.5+25));
//printf("--------MCU Temperature : %.1fC-------------\n\r",((((1.43-AD_Value)*43)/10000)+25));
//printf("*********MCU Temperature : %.1f¡æ*********\n\r", (200/77*(100*255/AD_Value-100)));
//printf("MCU Temperature : %.1f¡æ\n\r",((AD_Value*825/1024-760)/2.5+25));
printf("*********MCU Temperature : %.1fC******\n\r",(((1.43-AD_Value)*34/100000)+25));
}
HAL_Delay(1000);
java程序参考
http://blog.youkuaiyun.com/superce/article/details/78219707
演示视频地址
http://v.youku.com/v_show/id_XMzEwMTA0MTE2MA==.html
width="510" height="498" src="http://v.youku.com/v_show/id_XMzEwMTA0MTE2MA==.html">