第二一天 2015年08月11日 周二 例程:内部温度传感器实验
1.STM32F4有一个内部温度传感器,可以用来测量CPU及周围的温度。此温度传感器在内部和ADC1_IN16(STM32F40xx系列)或ADC1_IN18(STM32F42cxx/STM32F43xx系列)输入通道相连接,可以把传感器输出的电压转换为数字值。
2.支持温度范围:-40~125℃,精度±1.5。
3.温度计算公式:T(℃) = ((Vsense - V25) / Avg_Slope) + 25;
其中,V25 = Vsense在25℃时的数值(典型值0.76)
Avg_Slope = 温度与Vsense曲线的平均斜率(mv/℃或uv/℃)(典型值2.5mv/℃)
Vsense为内部传感器输出电压转换后的数字值
TFTLCD显示实验【二】-----图形绘制函数汇总(开发指南的搬运工)
①void LCD_SetCursor(u16 Xpos, u16 Ypos);
函数作用:设置光标位置
参数含义:Xpos:横坐标; Ypos:纵坐标
②void LCD_DrawPoint(u16 x,u16 y);
函数作用:画点
参数含义:x,y:坐标;  OINT_COLOR:此点的颜色
void LCD_Fast_DrawPoint(u16 x,u16 y,u16 color);
函数作用:快速画点
参数含义:x,y:坐标; color:颜色
③u16 LCD_ReadPoint(u16 x,u16 y);
函数作用:读取个某点的颜色值
参数含义:x,y:坐标; 返回值:此点的颜色
④void LCD_Display_Dir(u8 dir);
函数作用:设置LCD显示方向
参数含义:dir:0,竖屏;1,横屏
⑤void LCD_Set_Window(u16 sx,u16 sy,u16 width,u16 height);
函数作用:设置窗口,并自动设置画点坐标到窗口左上角(sx,sy).
参数含义:sx,sy:窗口起始坐标(左上角); width,height:窗口宽度和高度,必须大于0!! 窗体大小:width*height.
//68042,横屏时不支持窗口设置!!
⑥void LCD_Clear(u16 color);
函数作用:清屏函数
参数含义:color:要清屏的填充色
⑦void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color);
函数作用:在指定区域内填充单个颜色
参数含义:(sx,sy),(ex,ey):填充矩形对角坐标,区域大小为ex-sx+1)*(ey-sy+1) color:要填充的颜色
⑧void LCD_Color_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 *color);
函数作用:在指定区域内填充指定颜色块
参数含义:(sx,sy),(ex,ey):填充矩形对角坐标,区域大小为ex-sx+1)*(ey-sy+1) color:要填充的颜色
⑨void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2);
函数作用:画线
参数含义:x1,y1:起点坐标; x2,y2:终点坐标
⑩void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2);
函数作用:画矩形
参数含义:(x1,y1),(x2,y2):矩形的对角坐标
void LCD_Draw_Circle(u16 x0,u16 y0,u8 r);
函数作用:在指定位置画一个指定大小的圆
参数含义:(x,y):中心点; r :半径
--------------------------------------------------------------------------------------------------------------------------------------------
①
[mw_shl_code=c,true]//设置光标位置
//Xpos:横坐标
//Ypos:纵坐标
void LCD_SetCursor(u16 Xpos, u16 Ypos)
{
if(lcddev.id==0X9341||lcddev.id==0X5310)
{
LCD_WR_REG(lcddev.setxcmd);
LCD_WR_DATA(Xpos>>8);
LCD_WR_DATA(Xpos&0XFF);
LCD_WR_REG(lcddev.setycmd);
LCD_WR_DATA(Ypos>>8);
LCD_WR_DATA(Ypos&0XFF);
}else if(lcddev.id==0X6804)
{
if(lcddev.dir==1)Xpos=lcddev.width-1-Xpos;//横屏时处理
LCD_WR_REG(lcddev.setxcmd);
LCD_WR_DATA(Xpos>>8);
LCD_WR_DATA(Xpos&0XFF);
LCD_WR_REG(lcddev.setycmd);
LCD_WR_DATA(Ypos>>8);
LCD_WR_DATA(Ypos&0XFF);
}else if(lcddev.id==0X5510)
{
LCD_WR_REG(lcddev.setxcmd);
LCD_WR_DATA(Xpos>>8);
LCD_WR_REG(lcddev.setxcmd+1);
LCD_WR_DATA(Xpos&0XFF);
LCD_WR_REG(lcddev.setycmd);
LCD_WR_DATA(Ypos>>8);
LCD_WR_REG(lcddev.setycmd+1);
LCD_WR_DATA(Ypos&0XFF);
}else
{
if(lcddev.dir==1)Xpos=lcddev.width-1-Xpos;//横屏其实就是调转x,y坐标
LCD_WriteReg(lcddev.setxcmd, Xpos);
LCD_WriteReg(lcddev.setycmd, Ypos);
}
} [/mw_shl_code]
②
[mw_shl_code=c,true]//画点
//x,y:坐标
//POINT_COLOR:此点的颜色
void LCD_DrawPoint(u16 x,u16 y)
{
LCD_SetCursor(x,y); //设置光标位置
LCD_WriteRAM_Prepare(); //开始写入GRAM
LCD->LCD_RAM=POINT_COLOR;
}
//快速画点
//x,y:坐标
//color:颜色
void LCD_Fast_DrawPoint(u16 x,u16 y,u16 color)
{
if(lcddev.id==0X9341||lcddev.id==0X5310)
{
LCD_WR_REG(lcddev.setxcmd);
LCD_WR_DATA(x>>8);
LCD_WR_DATA(x&0XFF);
LCD_WR_REG(lcddev.setycmd);
LCD_WR_DATA(y>>8);
LCD_WR_DATA(y&0XFF);
}else if(lcddev.id==0X5510)
{
LCD_WR_REG(lcddev.setxcmd);LCD_WR_DATA(x>>8);
LCD_WR_REG(lcddev.setxcmd+1);LCD_WR_DATA(x&0XFF);
LCD_WR_REG(lcddev.setycmd);LCD_WR_DATA(y>>8);
LCD_WR_REG(lcddev.setycmd+1);LCD_WR_DATA(y&0XFF);
}else if(lcddev.id==0X6804)
{
if(lcddev.dir==1)x=lcddev.width-1-x;//横屏时处理
LCD_WR_REG(lcddev.setxcmd);
LCD_WR_DATA(x>>8);
LCD_WR_DATA(x&0XFF);
LCD_WR_REG(lcddev.setycmd);
LCD_WR_DATA(y>>8);
LCD_WR_DATA(y&0XFF);
}else
{
if(lcddev.dir==1)x=lcddev.width-1-x;//横屏其实就是调转x,y坐标
LCD_WriteReg(lcddev.setxcmd,x);
LCD_WriteReg(lcddev.setycmd,y);
}
LCD->LCD_REG=lcddev.wramcmd;
LCD->LCD_RAM=color;
}
[/mw_shl_code]
③
[mw_shl_code=c,true]//读取个某点的颜色值
//x,y:坐标
//返回值:此点的颜色
u16 LCD_ReadPoint(u16 x,u16 y)
{
vu16 r=0,g=0,b=0;
if(x>=lcddev.width||y>=lcddev.height)return 0; //超过了范围,直接返回
LCD_SetCursor(x,y);
if(lcddev.id==0X9341||lcddev.id==0X6804||lcddev.id==0X5310)LCD_WR_REG(0X2E);//9341/6804/3510 发送读GRAM指令
else if(lcddev.id==0X5510)LCD_WR_REG(0X2E00); //5510 发送读GRAM指令
else LCD_WR_REG(R34); //其他IC发送读GRAM指令
if(lcddev.id==0X9320)opt_delay(2); //FOR 9320,延时2us
LCD_RD_DATA(); //dummy Read
opt_delay(2);
r=LCD_RD_DATA(); //实际坐标颜色
if(lcddev.id==0X9341||lcddev.id==0X5310||lcddev.id==0X5510) //9341/NT35310/NT35510要分2次读出
{
opt_delay(2);
b=LCD_RD_DATA();
g=r&0XFF; //对于9341/5310/5510,第一次读取的是RG的值,R在前,G在后,各占8位
g<<=8;
}
if(lcddev.id==0X9325||lcddev.id==0X4535||lcddev.id==0X4531||lcddev.id==0XB505||lcddev.id==0XC505)return r; //这几种IC直接返回颜色值
else if(lcddev.id==0X9341||lcddev.id==0X5310||lcddev.id==0X5510)return (((r>>11)<<11)|((g>>10)<<5)|(b>>11));//ILI9341/NT35310/NT35510需要公式转换一下
else return LCD_BGR2RGB(r); //其他IC
}[/mw_shl_code]
④
[mw_shl_code=c,true]//设置LCD显示方向
//dir:0,竖屏;1,横屏
void LCD_Display_Dir(u8 dir)
{
if(dir==0) //竖屏
{
lcddev.dir=0; //竖屏
lcddev.width=240;
lcddev.height=320;
if(lcddev.id==0X9341||lcddev.id==0X6804||lcddev.id==0X5310)
{
lcddev.wramcmd=0X2C;
lcddev.setxcmd=0X2A;
lcddev.setycmd=0X2B;
if(lcddev.id==0X6804||lcddev.id==0X5310)
{
lcddev.width=320;
lcddev.height=480;
}
}else if(lcddev.id==0x5510)
{
lcddev.wramcmd=0X2C00;
lcddev.setxcmd=0X2A00;
lcddev.setycmd=0X2B00;
lcddev.width=480;
lcddev.height=800;
}else
{
lcddev.wramcmd=R34;
lcddev.setxcmd=R32;
lcddev.setycmd=R33;
}
}else //横屏
{
lcddev.dir=1; //横屏
lcddev.width=320;
lcddev.height=240;
if(lcddev.id==0X9341||lcddev.id==0X5310)
{
lcddev.wramcmd=0X2C;
lcddev.setxcmd=0X2A;
lcddev.setycmd=0X2B;
}else if(lcddev.id==0X6804)
{
lcddev.wramcmd=0X2C;
lcddev.setxcmd=0X2B;
lcddev.setycmd=0X2A;
}else if(lcddev.id==0x5510)
{
lcddev.wramcmd=0X2C00;
lcddev.setxcmd=0X2A00;
lcddev.setycmd=0X2B00;
lcddev.width=800;
lcddev.height=480;
}else
{
lcddev.wramcmd=R34;
lcddev.setxcmd=R33;
lcddev.setycmd=R32;
}
if(lcddev.id==0X6804||lcddev.id==0X5310)
{
lcddev.width=480;
lcddev.height=320;
}
}
LCD_Scan_Dir(DFT_SCAN_DIR); //默认扫描方向
} [/mw_shl_code]
⑤
[mw_shl_code=c,true]//设置窗口,并自动设置画点坐标到窗口左上角(sx,sy).
//sx,sy:窗口起始坐标(左上角)
//width,height:窗口宽度和高度,必须大于0!!
//窗体大小:width*height.
//68042,横屏时不支持窗口设置!!
void LCD_Set_Window(u16 sx,u16 sy,u16 width,u16 height)
{
u8 hsareg,heareg,vsareg,veareg;
u16 hsaval,heaval,vsaval,veaval;
width=sx+width-1;
height=sy+height-1;
if(lcddev.id==0X9341||lcddev.id==0X5310||lcddev.id==0X6804)//6804横屏不支持
{
LCD_WR_REG(lcddev.setxcmd);
LCD_WR_DATA(sx>>8);
LCD_WR_DATA(sx&0XFF);
LCD_WR_DATA(width>>8);
LCD_WR_DATA(width&0XFF);
LCD_WR_REG(lcddev.setycmd);
LCD_WR_DATA(sy>>8);
LCD_WR_DATA(sy&0XFF);
LCD_WR_DATA(height>>8);
LCD_WR_DATA(height&0XFF);
}else if(lcddev.id==0X5510)
{
LCD_WR_REG(lcddev.setxcmd);LCD_WR_DATA(sx>>8);
LCD_WR_REG(lcddev.setxcmd+1);LCD_WR_DATA(sx&0XFF);
LCD_WR_REG(lcddev.setxcmd+2);LCD_WR_DATA(width>>8);
LCD_WR_REG(lcddev.setxcmd+3);LCD_WR_DATA(width&0XFF);
LCD_WR_REG(lcddev.setycmd);LCD_WR_DATA(sy>>8);
LCD_WR_REG(lcddev.setycmd+1);LCD_WR_DATA(sy&0XFF);
LCD_WR_REG(lcddev.setycmd+2);LCD_WR_DATA(height>>8);
LCD_WR_REG(lcddev.setycmd+3);LCD_WR_DATA(height&0XFF);
}else //其他驱动IC
{
if(lcddev.dir==1)//横屏
{
//窗口值
hsaval=sy;
heaval=height;
vsaval=lcddev.width-width-1;
veaval=lcddev.width-sx-1;
}else
{
hsaval=sx;
heaval=width;
vsaval=sy;
veaval=height;
}
hsareg=0X50;heareg=0X51;//水平方向窗口寄存器
vsareg=0X52;veareg=0X53;//垂直方向窗口寄存器
//设置寄存器值
LCD_WriteReg(hsareg,hsaval);
LCD_WriteReg(heareg,heaval);
LCD_WriteReg(vsareg,vsaval);
LCD_WriteReg(veareg,veaval);
LCD_SetCursor(sx,sy); //设置光标位置
}
} [/mw_shl_code]
⑥
[mw_shl_code=c,true]//清屏函数
//color:要清屏的填充色
void LCD_Clear(u16 color)
{
u32 index=0;
u32 totalpoint=lcddev.width;
totalpoint*=lcddev.height; //得到总点数
if((lcddev.id==0X6804)&&(lcddev.dir==1))//6804横屏的时候特殊处理
{
lcddev.dir=0;
lcddev.setxcmd=0X2A;
lcddev.setycmd=0X2B;
LCD_SetCursor(0x00,0x0000); //设置光标位置
lcddev.dir=1;
lcddev.setxcmd=0X2B;
lcddev.setycmd=0X2A;
}else LCD_SetCursor(0x00,0x0000); //设置光标位置
LCD_WriteRAM_Prepare(); //开始写入GRAM
for(index=0;index<totalpoint;index++)
{
LCD->LCD_RAM=color;
}
} [/mw_shl_code]
⑦
[mw_shl_code=c,true]//在指定区域内填充单个颜色
//(sx,sy),(ex,ey):填充矩形对角坐标,区域大小为 ex-sx+1)*(ey-sy+1)
//color:要填充的颜色
void LCD_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 color)
{
u16 i,j;
u16 xlen=0;
u16 temp;
if((lcddev.id==0X6804)&&(lcddev.dir==1)) //6804横屏的时候特殊处理
{
temp=sx;
sx=sy;
sy=lcddev.width-ex-1;
ex=ey;
ey=lcddev.width-temp-1;
lcddev.dir=0;
lcddev.setxcmd=0X2A;
lcddev.setycmd=0X2B;
LCD_Fill(sx,sy,ex,ey,color);
lcddev.dir=1;
lcddev.setxcmd=0X2B;
lcddev.setycmd=0X2A;
}else
{
xlen=ex-sx+1;
for(i=sy;i<=ey;i++)
{
LCD_SetCursor(sx,i); //设置光标位置
LCD_WriteRAM_Prepare(); //开始写入GRAM
for(j=0;j<xlen;j++)LCD->LCD_RAM=color; //显示颜色
}
}
} [/mw_shl_code]
⑧
[mw_shl_code=c,true]//在指定区域内填充指定颜色块
//(sx,sy),(ex,ey):填充矩形对角坐标,区域大小为 ex-sx+1)*(ey-sy+1)
//color:要填充的颜色
void LCD_Color_Fill(u16 sx,u16 sy,u16 ex,u16 ey,u16 *color)
{
u16 height,width;
u16 i,j;
width=ex-sx+1; //得到填充的宽度
height=ey-sy+1; //高度
for(i=0;i<height;i++)
{
LCD_SetCursor(sx,sy+i); //设置光标位置
LCD_WriteRAM_Prepare(); //开始写入GRAM
for(j=0;j<width;j++)LCD->LCD_RAM=color[i*width+j];//写入数据
}
} [/mw_shl_code]
⑨
[mw_shl_code=c,true]//画线
//x1,y1:起点坐标
//x2,y2:终点坐标
void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2)
{
u16 t;
int xerr=0,yerr=0,delta_x,delta_y,distance;
int incx,incy,uRow,uCol;
delta_x=x2-x1; //计算坐标增量
delta_y=y2-y1;
uRow=x1;
uCol=y1;
if(delta_x>0)incx=1; //设置单步方向
else if(delta_x==0)incx=0;//垂直线
else {incx=-1;delta_x=-delta_x;}
if(delta_y>0)incy=1;
else if(delta_y==0)incy=0;//水平线
else{incy=-1;delta_y=-delta_y;}
if( delta_x>delta_y)distance=delta_x; //选取基本增量坐标轴
else distance=delta_y;
for(t=0;t<=distance+1;t++ )//画线输出
{
LCD_DrawPoint(uRow,uCol);//画点
xerr+=delta_x ;
yerr+=delta_y ;
if(xerr>distance)
{
xerr-=distance;
uRow+=incx;
}
if(yerr>distance)
{
yerr-=distance;
uCol+=incy;
}
}
} [/mw_shl_code]
⑩
[mw_shl_code=c,true]//画矩形
//(x1,y1),(x2,y2):矩形的对角坐标
void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2)
{
LCD_DrawLine(x1,y1,x2,y1);
LCD_DrawLine(x1,y1,x1,y2);
LCD_DrawLine(x1,y2,x2,y2);
LCD_DrawLine(x2,y1,x2,y2);
}[/mw_shl_code]
[mw_shl_code=c,true]//在指定位置画一个指定大小的圆
//(x,y):中心点
//r :半径
void LCD_Draw_Circle(u16 x0,u16 y0,u8 r)
{
int a,b;
int di;
a=0;b=r;
di=3-(r<<1); //判断下个点位置的标志
while(a<=b)
{
LCD_DrawPoint(x0+a,y0-b); //5
LCD_DrawPoint(x0+b,y0-a); //0
LCD_DrawPoint(x0+b,y0+a); //4
LCD_DrawPoint(x0+a,y0+b); //6
LCD_DrawPoint(x0-a,y0+b); //1
LCD_DrawPoint(x0-b,y0+a);
LCD_DrawPoint(x0-a,y0-b); //2
LCD_DrawPoint(x0-b,y0-a); //7
a++;
//使用Bresenham算法画圆
if(di<0)di +=4*a+6;
else
{
di+=10+4*(a-b);
b--;
}
}
} [/mw_shl_code]
总结:通过对以上程序进行汇总,可以发现,初看程序量较大,对每个函数稍微进行分析即可看出,除画圆等需要一定算法(无需过多涉猎)外,其他函数都是在进行了少量转化后进行屏幕寄存器的基础操作,也就是对常用寄存器的熟悉程度是处理好此类函数的关键。
|