已阅读5页,还剩157页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
综合任务温度报警器的设计与制作,教学导航任务单任务准备案例示范知识梳理与总结任务作业综合实训,教学导航,任务单,任务准备,8.1液晶显示器显示8.2键盘与单片机的连接8.3A/D接口技术8.4D/A接口技术8.5数字温度传感器,8.1液晶显示器显示,LCD(LiquidCrystalDisplay)是液晶显示器的缩写,液晶显示器是一种被动式的显示器,即液晶本身并不发光,而是利用液晶经过处理后能改变光线通过方向的特性,而达到白底黑字或黑底白字显示的目的。液晶显示器具有功耗低、抗干扰能力强等优点,因此被广泛应用。例如我们在手机、BP机、笔记本电脑和计算器上看到的都是液晶显示屏幕。由于LCD的控制必须使用专用的驱动电路,且LCD面板的接线需要采用特殊技巧,再加上LCD面板十分脆弱,因此一般不会单独使用,而是将LCD面板、驱动与控制电路组合成LCM模块(LiquidCrystalDisplayMould,LCM)一起使用。LCM的种类繁多,可以根据不同的场合、不同的需要选择不同类型的LCM,本书主要介绍1602字符型LCM(即两行显示,每行可显示16个字符)。,8.1.11602字符型LCM的特性及引脚功能,1字符型LCM的特性(1)具有字符发生器ROM(CharacterGenerateROM,CGROM),可显示192个57点阵字符,LCM显示的数字和字母部分的码值,刚好与ACSII码表中的数字和字母相同,所以在需要显示数字和字母时,只需要向LCM送入ASCII码即可。(2)具有64B的自定义字符RAM(CharacterGenerateRAM,CGRAM),可自行定义8个57点阵字符。(3)具有80B的数据显示存储器(DataDisplayRAM,DDRAM)。,2字符型LCM的引脚功能,字符型LCM通常有16个引脚,也有14个引脚,当选用14个引脚的LCM时,该LCM没有背光。,8.1.21602字特型LCM与单片机的连接,1直接访问方式连接该连接是由单片机的读(RD引脚)、写(WR引脚)和高位地址线共同控制LCM的E端,由高位地址线其中的两条分别与RS端和R/W端相连,由单片机的P0口LCM的DB0-DB7相连这样就构成了三总线(数据DB、地址总线AB和控制总线CB)的连接方式,如图所示。由于构成了三总线的结构,所以在软件控制上比较简单,用通过访问外部地址的方式就能访问LCM。但是,在使用这种连接方式时需要注意单片机的控制总线时序和地址总线时序必须要与LCM所需要的时序相匹配,否则将无法访问。,LCM与单片机的直接访问方式连接电路,2间接控制方式连接,是利用HD44780所具有的4位数据总线的功能,简化电路接口的一种连接方式,如图8-2所示。直接访问方式连接电路中需要增加与非门和反相器,从原理图上看很简单,但在实际焊接时,增加两个器件就增加了很多麻烦,另外增加器件也意味着增加了故障点,所以在实际使用时并不采用此电路。在图中,省去了4位数据线,电路连接十分简单,也没有多余的器件,对于参加比赛来说非常方便。,LCM与单片机的间接控制方式连接,2间接控制方式连接,但是由于LCM本身为速度较慢的器件,每一次数据传输大概需要几十微秒至几毫秒的时间,如果采用间接控制方式访问,每传送一个字节的数据需要访问两次LCM,这将占用大量的时间,使CPU变得很繁忙,甚至影响CPU处理其他数据的传输速度。所以在实际的硬件电路连接中常采用如图8-3所示的电路。采用这种连接方式不能构成三总线的结构,所以不能通过地址的形式直接访问,而是需要按照LCM的方式进行数据的传输,同时由于数据总线使用了8条,所以在数据传输的时间上与直接访问的时间相同,速度较间接控制方式提高了一倍,缩短了CPU对LCM的访问时间。,常用的LCM与单片机的连接,8.1.31602字符型LCM的指令集,提示,(1)对LCM操作主要是4种基本操作:写命令、写数据、读状态和读数据。(2)在进行写命令、写数据和读数据三种操作之前,必须先查询忙标志,当忙状态BF为0时,才能进行这三种操作。(3)LCM上电时,都必须按照一定时序对LCM进行初始化操作,主要分以下四步:设置LCM工作方式设置显示状态清屏:将光标设置为第1行第1列设置输入方式:设置光标移动方向并确定整体显示是否移动(4)当写一个显示字符后,如果没有再给光标重新定位,则DDRAM地址会自动加1或减1。(5)对LCM的读写操作必须符合读写操作时序,并要有一定的延时。读操作时,先设置RS和R/W状态,再设置E信号为高,这时从数据口读取数据,然后将E信号置低。写操作时,先设置RS和R/W状态,再设置数据,然后产生E的脉冲,案例17英文字符的液晶显示控制,利用基于HD44780控制芯片的1602液晶显示两行字符“Welcomeyou!”和“GuangZhou,2010”。,源程序(lcd.c),/液晶控制与显示程序#includeunsignedcharcount;sbitrs=P20;sbitrw=P21;sbiten=P22;voiddelay(unsignedintdely)unsignedchardely1;for(;dely0;dely-)for(dely1=10;dely10;dely1-);,/液晶显示器判忙函数unsignedcharbusy()unsignedcharlcd_status;rs=0;/寄存器选择rw=1;/读状态寄存器en=1;/开始读delay(100);lcd_status=P0;en=0;returnlcd_status;,源程序(lcd.c),/向液晶显示器写命令函数voidWR_Com(unsignedchartemp)/忙等待while(busy(),/向液晶显示器写数据函数voidWR_Data(unsignedchardat)while(busy(),源程序(lcd.c),/向液晶显示器写入显示数据函数/入口条件:液晶显示器行首地址(指示第一行还是第二行)和待显示数组的首地址voiddisp_lcd(unsignedcharaddr,unsignedchar*pstr)unsignedchari;WR_Com(addr);delay(100);for(i=0;istrlen(addr)i=0;delay(10000);,案例18空调预置温度的显示控制,两个LED数码管用于显示人工设置的希望环境温度值(简称预置温度),当实际环境温度高于该预置温度,则启动压缩机。两个LED数码管段选线分别连接到80C51的P1上,即两位预置温度的显示是通过将预置温度十位、个位数字BCD码分别由P1送入LED数码管来实现。,显示程序,#includeunsignedchartemp=30;main()unsignedchart10,t;t10=temp/10;t=temp%10;P0=(t100;j-);,bitkey()unsignedchartemp;bitflag=0;temp=P3;temp=temp|0 xfc;temp=temp0 xff;if(temp=0)returnflag;else,delay(25);temp=P3|0 xfc;temp=temp0 xff;if(temp=0)returnflag;elsevkey=temp;flag=1;while(temp)temp=P3|0 xfc;temp=temp0 xff;returnflag;,源程序(判断是否有键按下函数),2、采用中断方式,各个按键都接到一个与非门上,当有任何一个按键按下时,都会使与门输出为低电平,从而引起单片机的中断,它的好处是不用在主程序中不断地循环查询,如果有键按下,单片机再去做相应的处理。,实例8-2按照图8-9的电路,试编程实现由3个按键控制发光二极管的全亮、闪烁或全灭。,#includevoiddelay(unsignedchar);unsignedcharflag;voidmain()IT0=1;EA=1;EX0=1;while(1)switch(flag)case1:P0=0 x00;break;case2:P0=P0;delay(250);break;case3:P0=0 xff;break;,voiddelay(unsignedchart)unsignedchari,j;for(i=t;i0;i-)for(j=200;j0;j-);,中断服务函数,voidisr_int0()interrupt0unsignedcharkdata;kdata=P1;kdata=kdata0 xff;kdata=1;if(kdata!=0)kdata=1;if(kdata!=0)flag=3;elseflag=2;elseflag=1;,8.2.3矩阵式键盘接口技术,在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,一个端口(如P1口)就可以构成4*4=16个按键,在需要的键数比较多时,采用矩阵法来做键盘是合理的。,1、矩阵式键盘的结构,当按键没有按下时,所有的输入端都是高电平,代表无键按下。一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可判断是否有键按下了。,1、矩阵式键盘的结构,2、矩阵式键盘的按键识别方法行扫描法,1)判断键盘中有无键按下。将全部行线置低电平,然后检测列线的状态。只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。若所有列线均为高电平,则键盘中无键按下。2)判断闭合键所在的位置。在确认有键按下后,即可进入确定具体闭合键的过程。其方法是:依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。,2、矩阵式键盘的按键识别方法行扫描法,行扫描法,行扫描法识别按键的方法就象在二维平面上找确定的点,要在二维平面上找到确定的点。确定这点的横坐标:行线位置确定它的纵坐标:列线位置公式:键值=行号列数+列号,实例8-389S51单片机的P1口用作键盘I/O口,P0口用作输出口,用于输出所按键的键号(0F)。,89S51单片机的P1口用作键盘I/O口,键盘的列线接到P1口的低4位,键盘的行线接到P1口的高4位。列线P1.0P1.3分别接有4个上拉电阻到正电源+5V,并把列线P1.0P1.3设置为输入线,行线P1.4P1.7设置为输出线。4根行线和4根列线形成16个相交点。,行扫描识别步骤,(1)检测当前是否有键被按下:检测的方法是P1.4P1.7输出全“0”,读取P1.0P1.3的状态,若P1.0P1.3为全“1”,则无键闭合,否则有键闭合。(2)去除键抖动:当检测到有键按下后,延时一段时间再做下一步的检测判断。(3)若有键被按下,应识别出是哪一个键闭合。,识别键闭合的方法,对键盘的行线进行扫描。P1.4P1.7按下述4种组合依次输出:P1.71110P1.61101P1.51011P1.40111在每组行输出时读取P1.0P1.3,若全为“1”,则表示为这一行没有键闭合,否则有键闭合。由此得到闭合键的行值和列值,然后可采用计算法或查表法将闭合键的行值和列值转换成所定义的键值。,流程图,键盘扫描程序,#includeunsignedcharseg16=0 xc0,0 xf9,0 xa4,0 xb0,0 x99,0 x92,0 x82,0 xf8,0 x80,0 x90,0 x88,0 x83,0 xc6,0 xa1,0 x86,0 x8e;voiddelay(unsignedchar);unsignedcharkey_scan();voidmain()unsignedcharval_key;while(1)val_key=key_scan();if(val_key!=0 xff)P0=segval_key;,voiddelay(unsignedchart)unsignedchari,j;for(i=0;i4;/取行扫描码vkey=0 x0f;/将行扫描码取反switch(vkey)case1:keyNo+=0;break;/把行值加到列值中case2:keyNo+=4;break;case4:keyNo+=8;break;case8:keyNo+=12;break;dokdata=P1;kdata,案例19空调制冷控制系统预置温度控制,如下图所示,“UP”是“升温”按钮,接INT0,“DOWN”是“降温”按钮,接INT1。显然,该案例中,提高或降低调节温度均采用中断方式实现,按“UP”则产生外部中断0,按“DOWN”产生外部中断1。,源程序(主函数),调节温度的设置可分别在外部中断0和外部中断1的中断服务程序中实现,在中断服务程序中,调节温度放在变量temp(采用BCD码)中,每发生一次中断,temp中的数据加1或减1,并再分别由8051的P1、P2控制的两个数码管显示其温度值。,#includeunsignedchartemp=30;main()unsignedchart10,t;IT0=IT1=1;t10=temp/10;t=temp%10;P1=(t104)|(t,/按升温按钮的中断服务程序voidisr_int0()interrupt0unsignedchart10,t;if(temp30)temp+;t10=temp/10;t=temp%10;P1=(t1020)temp-;t10=temp/10;t=temp%10;P1=(t100;i-)/由于是动态扫描方式,因此显示电压值要循环若干次。dispvalue();addradc+;if(addradc=0 x7ffc)addradc=0 x7ff8;*addradc=0;,案例23高精度ADC与单片机的接口,源程序:,#includesbitCE=P30;sbitRC=P31;sbitSTS=P32;sbitLE=P25;sbitA0=P36;sbitCS=P33;#defineN0 x0fff/十二位转换unsignedlongresult=0;unsignedcharseg=0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f;unsignedcharbuf4;,源程序:,voiddelay(intn)inti;while(n-)for(i=0;i4;returntemp;,源程序:,voidchange()unsignedlongresult1;/用于中途的数据转换unsignedlongvol,vol_c;/电压显示,与电压的一个进位result1=result*10000;/*100*10*10v扩大一百倍,用来替代两位小数,扩大十倍用来小数点后第三位四舍五入,又乘以10,是最终电压。vol=result1/N;/vol=result/0 x0fff*10(v)vol_c=vol%10;if(vol_c=5)/四舍五入vol=vol+10;vol=vol/10;buf0=vol/1000;buf1=vol/100%10;buf2=vol/10%10;buf3=vol%10;,源程序:,voiddisplay()/显示子程序.inti;unsignedchartemp=0 xfe;for(i=0;i4;i+)LE=0;P2=temp;if(i=1)P1=segbufi+0 x80;elseP1=segbufi;LE=1;LE=0;delay(10);temp=(temp8;TL0=-50000;ET0=1;EA=1;TR0=1;ST=1;ST=0;/启动A/D转换while(1);,源程序,8.5数字温度传感器,DS18B20特点1单线结构,只需一根信号线和CPU相连。2不需要外部元件,直接输出串行数据。3可不需要外部电源,直接通过信号线供电,电源电压范围为3.3V5V。4测温精度高,测温范围为:-55+125,在-10+85范围内,精度为0.5。5测温分辨率高,当选用12位转换位数时,温度分辨率可达0.0625。6数字量的转换精度及转换时间可通过简单的编程来控制:9位精度的转换时间为93.75ms;10位精度的转换时间187.5ms;12位精度的转换时间750ms。7具有非易失性上、下限报警设定的功能,用户可方便地通过编程修改上、下限的数值。8可通过报警搜索命令识别哪片DS18B20采集的温度超越上、下限。,8.5.1DS18B20引脚及内部结构,1DS18B20引脚DS18B20的常用封装有3脚、8脚等几种形式。各脚含义如下:,DQ:数字信号输入输出端。GND:电源地端。VDD:外接供电电源输入端(在寄生电源接线时此脚应接地)。,2DS18B20内部结构,(1)64位光刻ROM,是生产厂家给每一个出厂的DS18B20命名的产品序列号,可以看作为该器件的地址序列号。其作用是使每一个出厂的DS18B20地址序列号都各不相同,这样,就可以实现一根总线上挂接多个DS18B20的目的。,(2)温度传感器,完成对温度的测量,输出格式为:16位符号扩展的二进制补码。当测温精度设置为12位时,分辨率为0.0625,即0.0625/LSB。,(2)温度传感器,完成对温度的测量,输出格式为:16位符号扩展的二进制补码。当测温精度设置为9位时,其二进制补码格式如下图所示,分辨率为0.5,即0.5/LSB。,(3)低温触发器TL、高温触发器TH,用于设置低温、高温的报警数值,两个寄存器均为8位。DS18B20完成一个周期的温度测量后,将测得的温度值(整数部分,包括符号位)和TL、TH相比较,如果小于TL,或大于TH,则表示温度越限,将该器件内的告警标志位置位,并对单片机发出的告警搜索命令作出响应。需要修改上、下限温度值时,只需使用一个功能命令即可对TL、TH写入,十分方便。,(4)内部存储器,包括一个9字节的高速暂存器和一个3字节的非易失寄存器E2PROM,后者是高温触发器和低温触发器和配置寄存器。,配置寄存器,配置寄存器用于设置DS18B20温度测量分辨率,数据格式如下:该寄存器中主要设置R1、R0的值,这两位值决定了DS18B20温度测量分辨率,其含义如下;,8.5.2DS18B20的读写操作,1ROM操作命令(1)读命令(33H):通过该命令主机可以读出DS18B20的ROM中的8位系列产品代码、48位产品序列号和8位CRC校验码。该命令仅限于单个DS18B20在线的情况。(2)选择定位命令(55H):当多片DS18B20在线时,主机发出该命令和一个64位数,DS18B20内部ROM与主机一致者,才响应命令。该命令也可用于单个DS18B20的情况。(3)查询命令(0F0H):该命令可查询总线上DS18B20的数目及其64位序列号。(4)跳过ROM序列号检测命令(0CCH):该命令允许主机跳过ROM序列号检测而直接对寄存器操作,该命令仅限于单个DS18B20在线的情况。(5)报警查询命令(0ECH):只有报警标志置位后,DS18B20才相应该命令。,2存储器操作命令,(1)写入命令(4EH):该命令可写入寄存器的第2、3、4字节,即高低温寄存器和配置寄存器。复位信号发出之前,三个字节必须写完。(2)读出命令(0BEH):该命令可读出寄存器中的内容,复位命令可终止读出。(3)开始转换命令(44H):该命令使DS18B20立即开始温度转换,当温度转换正在进行时,主机这时读总线将收到0;当温度转换结束时,主机这时读总线将收到1。若用信号线给DS18B20供电,则主机发出转换命令后,必须提供至少相应于分辨率的温度转换时间的上拉电平。(4)回调命令(088H):该命令把EEROM中的内容写到寄存器TH、TL及配置寄存器中。DS18B20上电时能自动写入。(5)复制命令(48H):该命令把寄存器TH、TL及配置寄存器中的内容写到EEROM中。(6)读电源标志命令(084H):主机发出该命令后,DS18B20将进行响应,发送电源标志,信号线供电发0,外接电源发1。,8.5.3DS18B20的复位及读写时序,1复位对DS18B20操作之前,首先要将它复位。(1)主机将信号线置为低电平,时间为480960s。(2)主机将信号线置为高电平,时间为1560s。480s960s15s60s60240s480sDQ(3)DS18B20发出60240s的低电平作为应答信号。单片机收到此信号后,表明复位成功,才能对DS18B20作其它操作,否则可能发生器件不存在、器件损坏或其他故障。,2写字节,单片机将DQ设置为低电平,延时15s产生写起始信号。将待写的数据以串行形式送一位至DQ端,DS18B20在1560s的时间内对DQ检测,如DQ为高电平,则写1,如DQ为低电平,则写0,从而完成了一个写周期。在开始另一个写周期前,必须有1s以上的高电平恢复期。,写“0”时序,写“1”时序,3读字节,当单片机准备从DS18B20温度传感器读取每一位数据时,应先发出启动读时序脉冲,即将DQ设置低电平1s以上,再使DQ上升为高电平,产生读起始信号。启动后等待15s,以便DS18B20能可靠地将温度数据送至DQ总线上,然后单片机开始读取DQ总线上的结果,单片机在完成取数据操作后,要等待至少45s,从而完成了一个读周期。在开始另一个读周期前,必须有1s以上的高电平恢复期。,案例26单片机与DS18B20传感器连接,用单片机AT89C52的P0.7口线经上拉后接至DS18B20的引脚2数据端,引脚1接电源地端,引脚3接+5V电源端。,源程序,#include#includesbitLE=P25;sbitDQ=P07;bitDS_IS_OK=1;unsignedcharseg=0 x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d,0 x07,0 x7f,0 x6f,0 x40,0 x00;/字段数组定义了12个元素,其中第11个元素是负号“-”的字/段码第12个元素为不显示的字段码,用于显示正温度值unsignedcharbuf4;unsignedinttemperature;voiddelay(unsignedinttime)/延时函数while(time-);,源程序(初始化函数和读字节函数),/DS18B20初始化函数unsignedcharInit_Ds18b20()unsignedcharstatus;DQ=1;delay(8);DQ=0;delay(90);DQ=1;delay(5);status=DQ;delay(60);returnstatus;,/读字节函数unsignedcharread()unsignedchari=0;unsignedchardat=0;DQ=1;_nop_();for(i=8;i0;i-)DQ=0;dat=1;DQ=1;_nop_();_nop_();if(DQ)dat|=0 x80;delay(30);DQ=1;return(dat);,源程序(写字节函数),voidwrite(unsignedchardat)unsignedchari;for(i=8;i0;i-)DQ=0;DQ=dat,源程序(采样温度函数),voidReadTemperature()unsignedchartempL=0;unsignedchartempH=0;if(Init_Ds18b20()=1)/DS18B20故障DS_IS_OK=0;elseDS_IS_OK=1;write(0 xcc);write(0 x44);Init_Ds18b20();write(0 xcc);write(0 xbe);tempL=read();tempH=read();temperature=(tempH8)|tempL;,/温度值显示处理函数voiddispute()unsignedinttemp,temp1;/用于中途的数据转换/以下if语句用于处理负温度值,因为保存的是温度值的补码if(temperature,源程序(显示函数),voiddisplay()/显示函数.inti,j;unsignedchartemp=0 xfe;for(j=0;j30;j+)/由于是动态显示方式,因此必须多次循环才能成功显示,很关键,处理不好温度值将显示不成功temp=0 xfe;for(i=0;i4;i+)LE=0;P2=temp;if(i=2)P1=segbufi+0 x80;elseP1=segbufi;LE=1;LE=0;delay(10);temp=(temp1)|1;P2=temp;/关显示,进行下一次测试,源程序(主函数),voidmain()ReadTemperature();delay(50000);delay(50000);while(1)if(DS_IS_OK=1)ReadTemperature();dispute();display();,案例27单片机控制空调制冷系统设计,空调制冷系统要控制的是空气温度,通过对压缩机的运行、停止进行控制,实际上单片直接控制的是压缩机的工作状态。要求该系统能够自动控制制冷压缩机的运行和停止(制冷压缩机工作,则将空气热量带走,环境温度下降),使环境温度保持在人们设定的温度上(调温范围为1030)。,1、确定任务,1)根据环境温度控制压缩机工作。控制参数是温度
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年放射科医生放射学影像诊断技术考核试卷及答案解析
- 2025年内蒙古自治区专业技术人员继续教育公需科目试题及答案
- 2025反假币考试题库及答案
- 2025年机械员考试题库及参考答案新
- 变压器火灾事故应急演练脚本
- 2025年火警故障测试题及答案
- 2025年焊工作业人员职业技能考试笔试试题含答案
- 2025年事业单位职测招考笔试试题含答案
- 2025年中级银行从业资格之中级银行业法律法规与综合能力通关提分题库及答案
- 2025建筑电工考试真题及答案
- 2025河北农业大学第二批招聘102人考试笔试参考题库附答案解析
- 小学感恩教育主题班会 课件
- 新媒体营销推广案例分析
- 2025北京市实验动物上岗证试题及答案
- 道路客运驾驶员从业资格年度考核报告
- 制药设备改造协议书
- 读书分享成品《窗边的小豆豆》课件
- 【2025年】员工食堂培训试题及答案
- 财务会计基本规范与操作手册
- 2025年大学《历史学》专业题库- 中国古代史的专题研究
- 隧道下穿燃气管道爆破施工技术方案
评论
0/150
提交评论