一、功能要求:
设备自检功能:
设备上电自检(检查传感器采集是否正常, DHT11有存在响应, 可以自检使用, )自检通过后,由串口打印设备状态信息。
自动控制功能:
进入自动控制模式, LCD显示温湿度信息 加热片制冷片风机状态。与上位机通信( 串口助手), 每2s发送设备状态信息(温湿度值,风机状态,制冷片状态,加热片状态)到上位机 。
阈值设置功能:
可以通过五向按键选择并调整温湿度的阈值大小。
可以通过上位机发送命令设定温湿度的阈值大小。
二、功能概述
模块 | 功能 |
LCD显示屏 | 显示温湿度, 风机开关情况 ,制冷片开关情况, 加热片开关情况, 温湿 度上下阈值 |
LED | 三个灯分别模拟风机 、制冷片, 加热片 。( 灯亮表示开, 灯灭表示关) |
PA0 | 电池电压采集(选做) |
串口 | 数据接收及下发数据控制 |
低温加热 | 当环境温度低于设置的阈值时, 加热片启动 。加热到温度阈值5度以上停止工作 |
高温降温 | 当环境温度高于设置的阈值时,制冷片启动 。降温到温度阈值5度以下停止工作 |
除湿 | 当环境湿度高于设置的阈值时, 风机和制冷片,加热片启动 。湿度低于设置的阈值停止。 |
三、除湿器项目设计说明
湿度高于阈值,加热片、制冷片、风机同时工作
温度也高于某一阈值,制冷片工作
四、项目实验
1.打开stm32cube max,创建新的工程,以STM32G030C8Tx芯片建立工程,配置相关引脚。
2.完成相关配置,生成hal库函数的标准代码
3.分别将Lcd和DHT11的驱动.c文件和头文件放到生成文件中的code的Src和Inc文件中
4.完成相关代码的编写,然后完成相关实验
五、代码解析
1.延时函数
滴答计时器是向下计数的,told是获取的计数器的初值,tnow是在每次循环的开始重新获取计数器的数值;如果told大于tnow代表计数器正常运行,tcnt就加一,如果全程没有错误,等到tcnt大于计数器初值的时候退出,计数结束;
如果中途出现told小于tnow时,就代表着循环了一圈了,用重载值减去tnow现在的值,再加上tnow,还是相当于tcnt就加一,等到tcnt大于计数器初值的时候退出,计数结束,实现延时功能。
static uint32_t fac_us = 0; //us延时倍乘数void delay_init(uint8_t SYSCLK)
{fac_us = SYSCLK;
}void delay_us(uint32_t nus)//100 6800
{uint32_t ticks;uint32_t told, tnow, tcnt = 0;uint32_t reload = SysTick->LOAD; //LOAD的值ticks = nus * fac_us; //需要的节拍数told = SysTick->VAL; // 24 刚进入时的计数器值while (1){tnow = SysTick->VAL;//22 20 0if (tnow != told){if (tnow < told)tcnt += told - tnow; //这里注意一下SYSTICK是一个递减的计数器就可以了.elsetcnt += reload - tnow + told;told = tnow;if (tcnt >= ticks)break; //时间超过/等于要延迟的时间,则退出.}};
}
void delay_ms(uint16_t nms)
{uint32_t i;for (i = 0; i < nms; i++)delay_us(1000);
}
2.定义全局变量和主函数
初始化LCD和DHT11,开始时检验DHT11是否正常,无论是否正常都反馈;如果DHT11正常的话,读取温湿度数据。
/* USER CODE BEGIN PFP */
uint8_t humiH;
uint8_t humiL;
uint8_t tempH;
uint8_t tempL;
int tempmax=30;
int tempmin=26;
int humimax=65;
float temp;
char lcdtem[16]="";
char lcdhum[16]="";
char humiset[16]="";
char tmaxset[16]="";
char tminset[16]="";
char devh[32]="devhot: off";
char devc[32]="devcold:off";
char fun[32]="fun: off";
char set[32]="";
char md[3]="CS";
int setmode=0;
int high=0;
int low=0;
int mode=0;
int color0=BLUE;
int color1=BLUE;
int color2=BLUE;
/* USER CODE END PFP */
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();MX_TIM16_Init();MX_ADC1_Init();/* USER CODE BEGIN 2 */Lcd_Init();Lcd_Clear(BLUE);delay_init(16);//根据频率确定参数 此时16MHZFS_DHT11_Init();//自检初始化函数 检测能否正常通信 只关心起始信号的正确性 不关心后面的数据HAL_Delay(500);if(!FS_DHT11_Init()) //根据0或1的返回值 由子函数可知 0自检成功 1表示失败{printf("check ok\n");Gui_DrawFont_GBK16(15,40,YELLOW,BLUE,"check ok ");}Lcd_Clear(BLUE);HAL_TIM_Base_Start_IT(&htim16);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */DHT11_Read_Data(&humiH,&humiL,&tempH,&tempL);temp = tempH + tempL*0.1;HAL_UART_Receive_IT(&huart1,set,10);dev_control();send_lcd();HAL_ADC_Start(&hadc1);//启动ADC转化HAL_ADC_PollForConversion(&hadc1,1000);//等待转换完成,多通道不可用uint32_t key = HAL_ADC_GetValue(&hadc1);//获取ADC转化值HAL_ADC_Stop(&hadc1);//停止ADC转化HAL_Delay(300);}/* USER CODE END 3 */
}
3.控制函数
将控制模式分为两种,模式1控制除湿,如果湿度大于阈值,进行除湿;模式2控制升温和降温,如果大于高温阈值,就进行降温;如果小于低温阈值,就进行升温。
void dev_control()
{if(mode==1){strcpy(md,"CS");if(humiH>humimax)//除湿{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2,0);strcpy(devh,"devhot: on");strcpy(devc,"devcold: on");strcpy(fun,"fun: on");}else{strcpy(devh,"devhot: off");strcpy(devc,"devcold:off");strcpy(fun,"fun: off");HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2,1);}}if(mode==0){strcpy(md,"KW");if(temp>tempmax)//高温 降温{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0 | GPIO_PIN_2,1);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,0);strcpy(devh,"devhot: off");strcpy(devc,"devcold: on");strcpy(fun,"fun: off");}else if(temp<(tempmax-5)){strcpy(devc,"devcold:off");HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,1);}if(temp<tempmin)//低温 加热{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1 | GPIO_PIN_2,1);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,0);strcpy(devh,"devhot: on");strcpy(devc,"devcold:off");strcpy(fun,"fun: off");}else if(temp>(tempmin+5)){strcpy(devh,"devhot: off");HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,1);}}
}
4.LCD数据显示
将temp等数值在屏幕中显示出来。
void send_lcd()
{sprintf(lcdtem,"Temp:%.2fC",temp);sprintf(lcdhum,"Humi:%d%%",humiH);sprintf(humiset,"HumiMax:%d%%",humimax);sprintf(tmaxset,"TempMax:%dC",tempmax);sprintf(tminset,"TempMin:%dC",tempmin);Gui_DrawFont_GBK16(5,5,YELLOW,BLUE,lcdtem);Gui_DrawFont_GBK16(100,5,WHITE,BLACK,md);Gui_DrawFont_GBK16(5,20,YELLOW,BLUE,lcdhum);Gui_DrawFont_GBK16(5,35,YELLOW,BLUE,devh);Gui_DrawFont_GBK16(5,50,YELLOW,BLUE,devc);Gui_DrawFont_GBK16(5,65,YELLOW,BLUE,fun);Gui_DrawFont_GBK16(5,80,YELLOW,color0,humiset);Gui_DrawFont_GBK16(5,95,YELLOW,color1,tmaxset);Gui_DrawFont_GBK16(5,110,YELLOW,color2,tminset);
}
5.按键控制
根据五向按键每个方向都可以产生不同参数,然后根据相应参数,进行控制阈值的改变
//上 2100-2000
//下 500-600
//左1500-1600
//右2900-3000
//中2500-2600
void change_data(int key)
{if((key>1900)&&(key<2200))//增加温度{if(low==1){tempmin++;}else if(high==1){tempmax++;}}else if((key>400)&&(key<700))//减小温度{if(low==1){tempmin--;}else if(high==1){tempmax--;}}else if((key>1400)&&(key<1700))//减小湿度{color0=BLACK;color1=BLUE;color2=BLUE;humimax--;}else if((key>2800)&&(key<3100))//增大湿度{color0=BLACK;color1=BLUE;color2=BLUE;humimax++;}else if((key>2400)&&(key<2700))//进入或退出调节模式{if(setmode == 0){setmode=1;high=1;low=0;color0=BLUE;color1=BLACK;color2=BLUE;}else if(setmode == 1){low=1;high=0;setmode=2;color0=BLUE;color1=BLUE;color2=BLACK;}else{setmode=0;color0=BLUE;color1=BLUE;color2=BLUE;}}
}
/* USER CODE END 4 */
6.输出重定向
int fputc(int ch,FILE *p)
{while(!(USART1->ISR &(1<<7)));USART1->TDR = ch;return ch;
}
7.ADC中断
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{HAL_ADC_Start(&hadc1);//启动ADC转化HAL_ADC_PollForConversion(&hadc1,1000);//等待转换完成,多通道不可用uint32_t key = HAL_ADC_GetValue(&hadc1);//获取ADC转化值HAL_ADC_Stop(&hadc1);//停止ADC转化change_data(key);
}
8.串口响应中断
查找到相关数据,并将收到的数据转化成字符串,然后向串口发送
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim==&htim16){printf("temp = %.2fC humi = %d%%\n %s %s %s ",temp,humiH,devh,devc,fun);}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if(strstr(set,"tempmax:")){sscanf(set,"tempmax:%d",&tempmax);printf("recvdata=%s",set);}else if(strstr(set,"tempmin:")){sscanf(set,"tempmin:%d",&tempmin);printf("recvdata=%s",set);}else if(strstr(set,"humimax:")){sscanf(set,"humimax:%d",&humimax);printf("recvdata=%s",set);}else if(strstr(set,"modeset==")){sscanf(set,"modeset==%d",&mode);printf("recvdata=%s",set);}
}
六、主函数完整代码
/* USER CODE BEGIN Header */
/********************************************************************************* @file : main.c* @brief : Main program body******************************************************************************* @attention** <h2><center>© Copyright (c) 2024 STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under BSD 3-Clause license,* the "License"; You may not use this file except in compliance with the* License. You may obtain a copy of the License at:* opensource.org/licenses/BSD-3-Clause********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "dht11.h"
#include <stdio.h>
#include "lcd.h"
#include "string.h"
static uint32_t fac_us = 0; //us延时倍乘数void delay_init(uint8_t SYSCLK)
{fac_us = SYSCLK;
}void delay_us(uint32_t nus)//100 6800
{uint32_t ticks;uint32_t told, tnow, tcnt = 0;uint32_t reload = SysTick->LOAD; //LOAD的值ticks = nus * fac_us; //需要的节拍数told = SysTick->VAL; // 24 刚进入时的计数器值while (1){tnow = SysTick->VAL;//22 20 0if (tnow != told){if (tnow < told)tcnt += told - tnow; //这里注意一下SYSTICK是一个递减的计数器就可以了.elsetcnt += reload - tnow + told;told = tnow;if (tcnt >= ticks)break; //时间超过/等于要延迟的时间,则退出.}};
}
void delay_ms(uint16_t nms)
{uint32_t i;for (i = 0; i < nms; i++)delay_us(1000);
}/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
uint8_t humiH;
uint8_t humiL;
uint8_t tempH;
uint8_t tempL;
int tempmax=30;
int tempmin=26;
int humimax=65;
float temp;
char lcdtem[16]="";
char lcdhum[16]="";
char humiset[16]="";
char tmaxset[16]="";
char tminset[16]="";
char devh[32]="devhot: off";
char devc[32]="devcold:off";
char fun[32]="fun: off";
char set[32]="";
char md[3]="CS";
int setmode=0;
int high=0;
int low=0;
int mode=0;
int color0=BLUE;
int color1=BLUE;
int color2=BLUE;
/* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void dev_control();
void send_lcd();
void change_data(int key);
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim==&htim16){printf("temp = %.2fC humi = %d%%\n %s %s %s ",temp,humiH,devh,devc,fun);}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{if(strstr(set,"tempmax:")){sscanf(set,"tempmax:%d",&tempmax);printf("recvdata=%s",set);}else if(strstr(set,"tempmin:")){sscanf(set,"tempmin:%d",&tempmin);printf("recvdata=%s",set);}else if(strstr(set,"humimax:")){sscanf(set,"humimax:%d",&humimax);printf("recvdata=%s",set);}else if(strstr(set,"modeset==")){sscanf(set,"modeset==%d",&mode);printf("recvdata=%s",set);}
}
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{HAL_ADC_Start(&hadc1);//启动ADC转化HAL_ADC_PollForConversion(&hadc1,1000);//等待转换完成,多通道不可用uint32_t key = HAL_ADC_GetValue(&hadc1);//获取ADC转化值HAL_ADC_Stop(&hadc1);//停止ADC转化change_data(key);
}
/* USER CODE END 0 *//*** @brief The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();MX_TIM16_Init();MX_ADC1_Init();/* USER CODE BEGIN 2 */Lcd_Init();Lcd_Clear(BLUE);delay_init(16);//根据频率确定参数 此时16MHZFS_DHT11_Init();//自检初始化函数 检测能否正常通信 只关心起始信号的正确性 不关心后面的数据HAL_Delay(500);if(!FS_DHT11_Init()) //根据0或1的返回值 由子函数可知 0自检成功 1表示失败{printf("check ok\n");Gui_DrawFont_GBK16(15,40,YELLOW,BLUE,"check ok ");}Lcd_Clear(BLUE);HAL_TIM_Base_Start_IT(&htim16);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */DHT11_Read_Data(&humiH,&humiL,&tempH,&tempL);temp = tempH + tempL*0.1;HAL_UART_Receive_IT(&huart1,set,10);dev_control();send_lcd();HAL_ADC_Start(&hadc1);//启动ADC转化HAL_ADC_PollForConversion(&hadc1,1000);//等待转换完成,多通道不可用uint32_t key = HAL_ADC_GetValue(&hadc1);//获取ADC转化值HAL_ADC_Stop(&hadc1);//停止ADC转化HAL_Delay(300);}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};/** Configure the main internal regulator output voltage*/HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}/** Initializes the peripherals clocks*/PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_ADC;PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_SYSCLK;if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 */
int fputc(int ch,FILE *p)
{while(!(USART1->ISR &(1<<7)));USART1->TDR = ch;return ch;
}//PB0 蒸发器
//PB1 制冷片
//PB2 风机
void dev_control()
{if(mode==1){strcpy(md,"CS");if(humiH>humimax)//除湿{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2,0);strcpy(devh,"devhot: on");strcpy(devc,"devcold: on");strcpy(fun,"fun: on");}else{strcpy(devh,"devhot: off");strcpy(devc,"devcold:off");strcpy(fun,"fun: off");HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2,1);}}if(mode==0){strcpy(md,"KW");if(temp>tempmax)//高温 降温{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0 | GPIO_PIN_2,1);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,0);strcpy(devh,"devhot: off");strcpy(devc,"devcold: on");strcpy(fun,"fun: off");}else if(temp<(tempmax-5)){strcpy(devc,"devcold:off");HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,1);}if(temp<tempmin)//低温 加热{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1 | GPIO_PIN_2,1);HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,0);strcpy(devh,"devhot: on");strcpy(devc,"devcold:off");strcpy(fun,"fun: off");}else if(temp>(tempmin+5)){strcpy(devh,"devhot: off");HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,1);}}
}
void send_lcd()
{sprintf(lcdtem,"Temp:%.2fC",temp);sprintf(lcdhum,"Humi:%d%%",humiH);sprintf(humiset,"HumiMax:%d%%",humimax);sprintf(tmaxset,"TempMax:%dC",tempmax);sprintf(tminset,"TempMin:%dC",tempmin);Gui_DrawFont_GBK16(5,5,YELLOW,BLUE,lcdtem);Gui_DrawFont_GBK16(100,5,WHITE,BLACK,md);Gui_DrawFont_GBK16(5,20,YELLOW,BLUE,lcdhum);Gui_DrawFont_GBK16(5,35,YELLOW,BLUE,devh);Gui_DrawFont_GBK16(5,50,YELLOW,BLUE,devc);Gui_DrawFont_GBK16(5,65,YELLOW,BLUE,fun);Gui_DrawFont_GBK16(5,80,YELLOW,color0,humiset);Gui_DrawFont_GBK16(5,95,YELLOW,color1,tmaxset);Gui_DrawFont_GBK16(5,110,YELLOW,color2,tminset);
}
//上 2100-2000
//下 500-600
//左1500-1600
//右2900-3000
//中2500-2600
void change_data(int key)
{if((key>1900)&&(key<2200))//增加温度{if(low==1){tempmin++;}else if(high==1){tempmax++;}}else if((key>400)&&(key<700))//减小温度{if(low==1){tempmin--;}else if(high==1){tempmax--;}}else if((key>1400)&&(key<1700))//减小湿度{color0=BLACK;color1=BLUE;color2=BLUE;humimax--;}else if((key>2800)&&(key<3100))//增大湿度{color0=BLACK;color1=BLUE;color2=BLUE;humimax++;}else if((key>2400)&&(key<2700))//进入或退出调节模式{if(setmode == 0){setmode=1;high=1;low=0;color0=BLUE;color1=BLACK;color2=BLUE;}else if(setmode == 1){low=1;high=0;setmode=2;color0=BLUE;color1=BLUE;color2=BLACK;}else{setmode=0;color0=BLUE;color1=BLUE;color2=BLUE;}}
}
/* USER CODE END 4 *//*** @brief This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef USE_FULL_ASSERT
/*** @brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* @param file: pointer to the source file name* @param line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT *//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/