本文是基于STM32F429在FreeRTOS下的HAL库开发,并验证在多任务不同优先级情况下运行情况。
LCD1602介绍:
是一个只能显示字母、数字、符号的点阵型液晶模块。一行可以显示16个字符,可以显示两行,所以叫做1602。
引脚定义:
数据和命令发送时序:
cubeMx引脚
引脚定义
LCD1602_D1 | PB15 |
LCD1602_D2 | PA2 |
LCD1602_D3 | PA3 |
LCD1602_D4 | PA4 |
LCD1602_D5 | PA5 |
LCD1602_D6 | PA6 |
LCD1602_D7 | PA7 |
LCD1602_D8 | PA8 |
LCD1602_RS | PB12 |
LCD1602_RW | PB13 |
LCD1602_EN | PB14 |
创建三个任务,其中任务“Task_100HZ”实现LCD的显示,Task_200HZ 实现数据采集和计算工作,Task_5HZ 显示Task_200HZ 任务计算的结果
/* definition and creation of Task_200HZ */
osThreadDef(Task_200HZ, StartTask_200, osPriorityNormal, 0, 128);
Task_200HZHandle = osThreadCreate(osThread(Task_200HZ), NULL);
/* definition and creation of Task_100HZ */
osThreadDef(Task_100HZ, StartTask_100HZ, osPriorityHigh, 0, 128);
Task_100HZHandle = osThreadCreate(osThread(Task_100HZ), NULL);
/* definition and creation of Task_5HZ */
osThreadDef(Task_5HZ, StartTask_5HZ, osPriorityIdle, 0, 128);
Task_5HZHandle = osThreadCreate(osThread(Task_5HZ), NULL);
LCD1602.C 代码实现
/******************************************************************************
* 函数名称:void GPIO_Configuration() *
* 函数功能:LCD1602引脚初始化 *
* 输入参数:无 *
* 返回值 :无 *
* 其他说明: *
******************************************************************************/
/*******************根据自己的硬件引脚做修改*****************************************/
void GPIO_Configuration()
{
* *
}
/******************************************************************************
* 函数名称:void LCD1602_Init() *
* 函数功能:LCD1602初始化 *
* 输入参数:无 *
* 返回值 :无 *
* 其他说明: *
******************************************************************************/
void LCD1602_Init()
{
GPIO_Configuration(); //初始化引脚
LCD1602_Write_Cmd( 0x38 ); //显示模式设置
delay_ms( 5 );
LCD1602_Write_Cmd( 0x0c ); //显示开及光标设置
delay_ms( 5 );
LCD1602_Write_Cmd( 0x06 ); //显示光标移动位置
delay_ms( 5 );
LCD1602_Write_Cmd( 0x01 ); //显示清屏
delay_ms( 5 );
}
void DATAOUT( cmd ){
HAL_GPIO_WritePin( LCD1602_D1_GPIO_Port, LCD1602_D1_Pin, ((cmd>>0)&0x01));
HAL_GPIO_WritePin( LCD1602_D2_GPIO_Port, LCD1602_D2_Pin, ((cmd>>1)&0x01));
HAL_GPIO_WritePin( LCD1602_D3_GPIO_Port, LCD1602_D3_Pin, ((cmd>>2)&0x01));
HAL_GPIO_WritePin( LCD1602_D4_GPIO_Port, LCD1602_D4_Pin, ((cmd>>3)&0x01));
HAL_GPIO_WritePin( LCD1602_D5_GPIO_Port, LCD1602_D5_Pin, ((cmd>>4)&0x01));
HAL_GPIO_WritePin( LCD1602_D6_GPIO_Port, LCD1602_D6_Pin, ((cmd>>5)&0x01));
HAL_GPIO_WritePin( LCD1602_D7_GPIO_Port, LCD1602_D7_Pin, ((cmd>>6)&0x01));
HAL_GPIO_WritePin( LCD1602_D8_GPIO_Port, LCD1602_D8_Pin, ((cmd>>7)&0x01));
}
/******************************************************************************
* 函数名称:void LCD1602_Write_Cmd(u8 cmd) *
* 函数功能:写命令函数 *
* 输入参数: cmd 命令 *
* 返回值 :无 *
* 其他说明: *
******************************************************************************/
void LCD1602_Write_Cmd( u8 cmd )
{
LCD_RS_Clr();
LCD_RW_Clr();
DATAOUT( cmd );
delay_us( 500 );//这个延迟时间是实际调试结果,太短会造成显示不全的问题
LCD_EN_Set();
delay_us( 500 );
LCD_EN_Clr();
}
/******************************************************************************
* 函数名称:void LCD1602_Write_Dat(u8 date) *
* 函数功能:写数据函数 *
* 输入参数: date 数据 *
* 返回值 :无 *
* 其他说明: *
******************************************************************************/
void LCD1602_Write_Dat( u8 data )
{
LCD_RS_Set();
LCD_RW_Clr();
DATAOUT( data );
delay_us( 500 );
LCD_EN_Set();
delay_us( 500 );
LCD_EN_Clr();
}
/******************************************************************************
* 函数名称:void LCD1602_ClearScreen() *
* 函数功能:1602清屏函数 *
* 输入参数:无 *
* 返回值 :无 *
* 其他说明: *
******************************************************************************/
void LCD1602_ClearScreen()
{
LCD1602_Write_Cmd( 0x01 );
}
/******************************************************************************
* 函数名称:void LCD1602_Set_Cursor(u8 x, u8 y) *
* 函数功能:设置1602位置函数 *
* 输入参数:x 横坐标 y 纵坐标 *
* 返回值 :无 *
* 其他说明: *
******************************************************************************/
void LCD1602_Set_Cursor( u8 x, u8 y )
{
u8 addr;
if ( y == 0 )
addr = 0x00 + x;
else
addr = 0x40 + x;
LCD1602_Write_Cmd( addr | 0x80 );
}
/******************************************************************************
* 函数名称:void LCD1602_Show_Str( u8 x, u8 y, u8 *str ) *
* 函数功能:指定位置显示字符串函数 *
* 输入参数:x 横坐标 y 纵坐标 *str 字符串 *
* 返回值 : 无 *
* 其他说明: *
******************************************************************************/
void LCD1602_Show_Str( u8 x, u8 y, u8 *str )
{
LCD1602_Set_Cursor( x, y );
while ( *str != '\0' )
{
LCD1602_Write_Dat( *str++ );
}
}
/* USER CODE BEGIN Header_StartTask_100HZ */
void delay(u16 z)
{
u16 x,y;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}
/**
* @brief Task_100HZ 任务 驱动 LCD1602
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask_100HZ */
void StartTask_100HZ(void const * argument)
{
/* USER CODE BEGIN StartTask_100HZ */
LCD1602_Init();
/* Infinite loop */
for(;;)
{
LCD1602_Write_Cmd(0x01); //清屏
delay(10);
LCD1602_Show_Str(0,0,"I want to bring");
LCD1602_Show_Str(0,1,"out the secret");
delay_ms(1500);
LCD1602_Write_Cmd(0x01); //清屏
delay(10);
LCD1602_Show_Str(0,0,"of nature and");
LCD1602_Show_Str(0,1,"apply them for");
delay_ms(1500);
LCD1602_Write_Cmd(0x01); //清屏
delay(10);
LCD1602_Show_Str(0,0,"the happiness of");
LCD1602_Show_Str(0,1,"man.I don't know");
delay_ms(1500);
LCD1602_Write_Cmd(0x01); //清屏
delay(10);
LCD1602_Show_Str(0,0,"of any better s-");
LCD1602_Show_Str(0,1,"-ervice to offer");
delay_ms(1500);
LCD1602_Write_Cmd(0x01); //清屏
delay(10);
LCD1602_Show_Str(0,0,"for the short t-");
LCD1602_Show_Str(0,1,"-ime we are in");
delay_ms(1500);
LCD1602_Write_Cmd(0x01); //清屏
delay(10);
LCD1602_Show_Str(0,0,"the world.");
LCD1602_Show_Str(0,1,"---Thomas Edison");
delay_ms(1500);
;
printf("LCD1206 test\r\n");
osDelay(500);
}
/* USER CODE END StartTask_100HZ */
}
实验现象:
以上在 StartTask_100HZ 任务 优先级最高的情况下,由于StartTask_100HZ 的运行时间占用资源好几秒 只有在程序运行到最后 osDelay(500) 之后才进入堵塞状态,释放资源,导致 其他任务不能得到及时的运行。
总结:
在FreeRTOS 中为了避免影响其他任务的实时运行,程序运行时间长的任务尽量降低优先级。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)