diff --git a/HARDWARE/DAC/dac.c b/HARDWARE/DAC/dac.c index d678638..50fbbe2 100644 --- a/HARDWARE/DAC/dac.c +++ b/HARDWARE/DAC/dac.c @@ -1,51 +1,51 @@ -#include "dac.h" -////////////////////////////////////////////////////////////////////////////////// -//本程序只供学习使用,未经作者许可,不得用于其它任何用途 -//ALIENTEK STM32F407开发板 -//DAC 驱动代码 -//正点原子@ALIENTEK -//技术论坛:www.openedv.com -//创建日期:2014/5/6 -//版本:V1.0 -//版权所有,盗版必究。 -//Copyright(C) 广州市星翼电子科技有限公司 2014-2024 -//All rights reserved -////////////////////////////////////////////////////////////////////////////////// - - -//DAC通道1输出初始化 -void Dac1_Init(void) -{ - GPIO_InitTypeDef GPIO_InitStructure; - DAC_InitTypeDef DAC_InitType; - - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟 - RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能DAC时钟 - - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入 - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉 - GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化 - - DAC_InitType.DAC_Trigger=DAC_Trigger_None; //不使用触发功能 TEN1=0 - DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_Noise;//不使用波形发生 - DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置 - DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ; //DAC1输出缓存关闭 BOFF1=1 - DAC_Init(DAC_Channel_1,&DAC_InitType); //初始化DAC通道1 - - DAC_Cmd(DAC_Channel_1, ENABLE); //使能DAC通道1 - - DAC_SetChannel1Data(DAC_Align_12b_R, 0); //12位右对齐数据格式设置DAC值 -} -//设置通道1输出电压 -//vol:0~3300,代表0~3.3V -void Dac1_Set_Vol(u16 vol) -{ - double temp=vol; - temp/=1000; - temp=temp*4096/3.3; - DAC_SetChannel1Data(DAC_Align_12b_R,temp);//12位右对齐数据格式设置DAC值 -} +//#include "dac.h" +//////////////////////////////////////////////////////////////////////////////////// +////本程序只供学习使用,未经作者许可,不得用于其它任何用途 +////ALIENTEK STM32F407开发板 +////DAC 驱动代码 +////正点原子@ALIENTEK +////技术论坛:www.openedv.com +////创建日期:2014/5/6 +////版本:V1.0 +////版权所有,盗版必究。 +////Copyright(C) 广州市星翼电子科技有限公司 2014-2024 +////All rights reserved +//////////////////////////////////////////////////////////////////////////////////// +// + +////DAC通道1输出初始化 +//void Dac1_Init(void) +//{ +// GPIO_InitTypeDef GPIO_InitStructure; +// DAC_InitTypeDef DAC_InitType; +// +// RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟 +// RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//使能DAC时钟 +// +// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;//4 +// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;//模拟输入 +// GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉 +// GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化 + +// DAC_InitType.DAC_Trigger=DAC_Trigger_None; //不使用触发功能 TEN1=0 +// DAC_InitType.DAC_WaveGeneration=DAC_WaveGeneration_Noise;//不使用波形发生 +// DAC_InitType.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置 +// DAC_InitType.DAC_OutputBuffer=DAC_OutputBuffer_Disable ; //DAC1输出缓存关闭 BOFF1=1 +// DAC_Init(DAC_Channel_1,&DAC_InitType); //初始化DAC通道1 + +// DAC_Cmd(DAC_Channel_1, ENABLE); //使能DAC通道1 +// +// DAC_SetChannel1Data(DAC_Align_12b_R, 0); //12位右对齐数据格式设置DAC值 +//} +////设置通道1输出电压 +////vol:0~3300,代表0~3.3V +//void Dac1_Set_Vol(u16 vol) +//{ +// double temp=vol; +// temp/=1000; +// temp=temp*4096/3.3; +// DAC_SetChannel1Data(DAC_Align_12b_R,temp);//12位右对齐数据格式设置DAC值 +//} diff --git a/HARDWARE/KEY/key.c b/HARDWARE/KEY/key.c new file mode 100644 index 0000000..bdf2a86 --- /dev/null +++ b/HARDWARE/KEY/key.c @@ -0,0 +1,82 @@ +#include "key.h" +#include "delay.h" +#include "lcd.h" +////////////////////////////////////////////////////////////////////////////////// +//本程序只供学习使用,未经作者许可,不得用于其它任何用途 +//ALIENTEK STM32F407开发板 +//按键输入驱动代码 +//正点原子@ALIENTEK +//技术论坛:www.openedv.com +//创建日期:2014/5/3 +//版本:V1.0 +//版权所有,盗版必究。 +//Copyright(C) 广州市星翼电子科技有限公司 2014-2024 +//All rights reserved +////////////////////////////////////////////////////////////////////////////////// + +//按键初始化函数 +void KEY_Init(void) +{ + + GPIO_InitTypeDef GPIO_InitStructure; + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOA,GPIOE时钟 + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; //KEY0 KEY1 KEY2对应引脚 + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式 + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉 + GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE2,3,4 + + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//WK_UP对应引脚PA0 + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN ;//下拉 + GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA0 + +} +//按键处理函数 +//返回按键值 +//mode:0,不支持连续按;1,支持连续按; +//0,没有任何按键按下 +//1,KEY0按下 +//2,KEY1按下 +//3,KEY2按下 +//4,WKUP按下 WK_UP +//注意此函数有响应优先级,KEY0>KEY1>KEY2>WK_UP!! +u8 KEY_Scan(u8 mode) +{ + static u8 key_up=1;//按键按松开标志u + //u8 runstop=1; + + if(mode)key_up=1; //支持连按 + if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1)) + { + delay_ms(10);//去抖动 + key_up=0; + if(KEY0==0)return 0; + else if(KEY1==0)return 2; + else if(KEY2==0)return 3; + else if(WK_UP==1)return 4; + }else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)key_up=1; + return 1;// 无按键按下 +} + + + + + + + + + + + + + + + + + + + + diff --git a/HARDWARE/KEY/key.h b/HARDWARE/KEY/key.h new file mode 100644 index 0000000..07d0d7e --- /dev/null +++ b/HARDWARE/KEY/key.h @@ -0,0 +1,41 @@ +#ifndef __KEY_H +#define __KEY_H +#include "sys.h" +////////////////////////////////////////////////////////////////////////////////// +//本程序只供学习使用,未经作者许可,不得用于其它任何用途 +//ALIENTEK STM32F407开发板 +//按键输入驱动代码 +//正点原子@ALIENTEK +//技术论坛:www.openedv.com +//创建日期:2014/5/3 +//版本:V1.0 +//版权所有,盗版必究。 +//Copyright(C) 广州市星翼电子科技有限公司 2014-2024 +//All rights reserved +////////////////////////////////////////////////////////////////////////////////// + +/*下面的方式是通过直接操作库函数方式读取IO*/ +#define KEY0 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4) //PE4 +#define KEY1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3) //PE3 +#define KEY2 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2) //PE2 +#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) //PA0 + + +/*下面方式是通过位带操作方式读取IO*/ +/* +#define KEY0 PEin(4) //PE4 +#define KEY1 PEin(3) //PE3 +#define KEY2 PEin(2) //P32 +#define WK_UP PAin(0) //PA0 +*/ + + +#define KEY0_PRES 1 +#define KEY1_PRES 2 +#define KEY2_PRES 3 +#define WKUP_PRES 4 + +void KEY_Init(void); //IO初始化 +u8 KEY_Scan(u8); //按键扫描函数 + +#endif diff --git a/HARDWARE/LCD/lcd.c b/HARDWARE/LCD/lcd.c index a8d5c11..8a01cd3 100644 --- a/HARDWARE/LCD/lcd.c +++ b/HARDWARE/LCD/lcd.c @@ -2959,7 +2959,25 @@ void LCD_ShowString(u16 x,u16 y,u16 width,u16 height,u8 size,u8 *p) } } +void LCD_ShowFloat(u16 x, u16 y, float num) +{ + u16 temp; + temp=num; + LCD_ShowxNum(x,y,temp,2,12,1); //显示N个整数部分 + LCD_ShowChar(x+12,y,'.',12,1); //显示小数点 + temp=((num-temp)*100); + LCD_ShowxNum(x+18,y,temp,2,12,1); //显示小数部分 +} +void LCD_ShowData(float Vmax,float Vmin,float Vpp) +{ + LCD_ShowString(0,201,66,12,12,"Vmax= V"); + LCD_ShowFloat(30,201,Vmax); + LCD_ShowString(84,201,66,12,12,"Vmin= V"); + LCD_ShowFloat(114,201,Vmin); + LCD_ShowString(156,201,66,12,12,"Vpp= V"); + LCD_ShowFloat(180,201,Vpp); +} diff --git a/HARDWARE/LCD/lcd.h b/HARDWARE/LCD/lcd.h index 993090c..c605697 100644 --- a/HARDWARE/LCD/lcd.h +++ b/HARDWARE/LCD/lcd.h @@ -2,79 +2,7 @@ #define __LCD_H #include "sys.h" #include "stdlib.h" -////////////////////////////////////////////////////////////////////////////////// -//本程序只供学习使用,未经作者许可,不得用于其它任何用途 -//ALIENTEK STM32F407开发板 -//2.4寸/2.8寸/3.5寸/4.3寸/7寸 TFT液晶驱动 -//支持驱动IC型号包括:ILI9341/ILI9325/RM68042/RM68021/ILI9320/ILI9328/LGDP4531/LGDP4535/ -// SPFD5408/1505/B505/C505/NT35310/NT35510/SSD1963等 -//正点原子@ALIENTEK -//技术论坛:www.openedv.com -//创建日期:2010/7/4 -//版本:V3.0 -//版权所有,盗版必究。 -//Copyright(C) 广州市星翼电子科技有限公司 2014-2024 -//All rights reserved -//******************************************************************************** -//V1.2修改说明 -//支持了SPFD5408的驱动,另外把液晶ID直接打印成HEX格式.方便查看LCD驱动IC. -//V1.3 -//加入了快速IO的支持 -//修改了背光控制的极性(适用于V1.8及以后的开发板版本) -//对于1.8版本之前(不包括1.8)的液晶模块,请修改LCD_Init函数的LCD_LED=1;为LCD_LED=1; -//V1.4 -//修改了LCD_ShowChar函数,使用画点功能画字符。 -//加入了横竖屏显示的支持 -//V1.5 20110730 -//1,修改了B505液晶读颜色有误的bug. -//2,修改了快速IO及横竖屏的设置方式. -//V1.6 20111116 -//1,加入对LGDP4535液晶的驱动支持 -//V1.7 20120713 -//1,增加LCD_RD_DATA函数 -//2,增加对ILI9341的支持 -//3,增加ILI9325的独立驱动代码 -//4,增加LCD_Scan_Dir函数(慎重使用) -//6,另外修改了部分原来的函数,以适应9341的操作 -//V1.8 20120905 -//1,加入LCD重要参数设置结构体lcddev -//2,加入LCD_Display_Dir函数,支持在线横竖屏切换 -//V1.9 20120911 -//1,新增RM68042驱动(ID:6804),但是6804不支持横屏显示!!原因:改变扫描方式, -//导致6804坐标设置失效,试过很多方法都不行,暂时无解。 -//V2.0 20120924 -//在不硬件复位的情况下,ILI9341的ID读取会被误读成9300,修改LCD_Init,将无法识别 -//的情况(读到ID为9300/非法ID),强制指定驱动IC为ILI9341,执行9341的初始化。 -//V2.1 20120930 -//修正ILI9325读颜色的bug。 -//V2.2 20121007 -//修正LCD_Scan_Dir的bug。 -//V2.3 20130120 -//新增6804支持横屏显示 -//V2.4 20131120 -//1,新增NT35310(ID:5310)驱动器的支持 -//2,新增LCD_Set_Window函数,用于设置窗口,对快速填充,比较有用,但是该函数在横屏时,不支持6804. -//V2.5 20140211 -//1,新增NT35510(ID:5510)驱动器的支持 -//V2.6 20140504 -//1,新增ASCII 24*24字体的支持(更多字体用户可以自行添加) -//2,修改部分函数参数,以支持MDK -O2优化 -//3,针对9341/35310/35510,写时间设置为最快,尽可能的提高速度 -//4,去掉了SSD1289的支持,因为1289实在是太慢了,读周期要1us...简直奇葩.不适合F4使用 -//5,修正68042及C505等IC的读颜色函数的bug. -//V2.7 20140710 -//1,修正LCD_Color_Fill函数的一个bug. -//2,修正LCD_Scan_Dir函数的一个bug. -//V2.8 20140721 -//1,解决MDK使用-O2优化时LCD_ReadPoint函数读点失效的问题. -//2,修正LCD_Scan_Dir横屏时设置的扫描方式显示不全的bug. -//V2.9 20141130 -//1,新增对SSD1963 LCD的支持. -//2,新增LCD_SSD_BackLightSet函数 -//3,取消ILI93XX的Rxx寄存器定义 -//V3.0 20150423 -//修改SSD1963 LCD屏的驱动参数. -////////////////////////////////////////////////////////////////////////////////// + //LCD重要参数集 typedef struct @@ -176,7 +104,10 @@ void LCD_WriteRAM(u16 RGB_Code); void LCD_SSD_BackLightSet(u8 pwm); //SSD1963 背光控制 void LCD_Scan_Dir(u8 dir); //设置屏扫描方向 void LCD_Display_Dir(u8 dir); //设置屏幕显示方向 -void LCD_Set_Window(u16 sx,u16 sy,u16 width,u16 height); //设置窗口 +void LCD_Set_Window(u16 sx,u16 sy,u16 width,u16 height); //设置窗口 +void LCD_ShowData(float Vmax,float Vmin,float Vpp); +void LCD_ShowFloat(u16 x, u16 y, float num); + //LCD分辨率设置 #define SSD_HOR_RESOLUTION 800 //LCD水平分辨率 #define SSD_VER_RESOLUTION 480 //LCD垂直分辨率 diff --git a/HARDWARE/TOUCH/rtouch.c b/HARDWARE/TOUCH/rtouch.c new file mode 100644 index 0000000..8ca44a3 --- /dev/null +++ b/HARDWARE/TOUCH/rtouch.c @@ -0,0 +1,465 @@ +#include "rtouch.h" +#include "lcd.h" +#include "delay.h" +#include "stdlib.h" +#include "math.h" +#include "led.h" + + +_m_tp_dev tp_dev= +{ + TP_Init, + TP_Scan, + TP_Adjust, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +}; +//默认为touchtype=0的数据. +u8 CMD_RDX=0XD0; +u8 CMD_RDY=0X90; + +//SPI写数据 +//向触摸屏IC写入1byte数据 +//num:要写入的数据 +void TP_Write_Byte(u8 num) +{ + u8 count=0; + for(count=0;count<8;count++) + { + if(num&0x80)TDIN=1; + else TDIN=0; + num<<=1; + TCLK=0; + delay_us(1); + TCLK=1; //上升沿有效 + } +} +//SPI读数据 +//从触摸屏IC读取adc值 +//CMD:指令 +//返回值:读到的数据 +u16 TP_Read_AD(u8 CMD) +{ + u8 count=0; + u16 Num=0; + TCLK=0; //先拉低时钟 + TDIN=0; //拉低数据线 + TCS=0; //选中触摸屏IC + TP_Write_Byte(CMD);//发送命令字 + delay_us(6);//ADS7846的转换时间最长为6us + TCLK=0; + delay_us(1); + TCLK=1; //给1个时钟,清除BUSY + delay_us(1); + TCLK=0; + for(count=0;count<16;count++)//读出16位数据,只有高12位有效 + { + Num<<=1; + TCLK=0; //下降沿有效 + delay_us(1); + TCLK=1; + if(DOUT)Num++; + } + Num>>=4; //只有高12位有效. + TCS=1; //释放片选 + return(Num); +} +//读取一个坐标值(x或者y) +//连续读取READ_TIMES次数据,对这些数据升序排列, +//然后去掉最低和最高LOST_VAL个数,取平均值 +//xy:指令(CMD_RDX/CMD_RDY) +//返回值:读到的数据 +#define READ_TIMES 5 //读取次数 +#define LOST_VAL 1 //丢弃值 +u16 TP_Read_XOY(u8 xy) +{ + u16 i, j; + u16 buf[READ_TIMES]; + u16 sum=0; + u16 temp; + for(i=0;ibuf[j])//升序排列 + { + temp=buf[i]; + buf[i]=buf[j]; + buf[j]=temp; + } + } + } + sum=0; + for(i=LOST_VAL;i1.05||d1==0||d2==0)//不合格 + { + cnt=0; + TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,WHITE); //清除点4 + TP_Drow_Touch_Point(20,20,RED); //画点1 + TP_Adj_Info_Show(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//显示数据 + continue; + } + tem1=abs(pos_temp[0][0]-pos_temp[2][0]);//x1-x3 + tem2=abs(pos_temp[0][1]-pos_temp[2][1]);//y1-y3 + tem1*=tem1; + tem2*=tem2; + d1=sqrt(tem1+tem2);//得到1,3的距离 + + tem1=abs(pos_temp[1][0]-pos_temp[3][0]);//x2-x4 + tem2=abs(pos_temp[1][1]-pos_temp[3][1]);//y2-y4 + tem1*=tem1; + tem2*=tem2; + d2=sqrt(tem1+tem2);//得到2,4的距离 + fac=(float)d1/d2; + if(fac<0.95||fac>1.05)//不合格 + { + cnt=0; + TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,WHITE); //清除点4 + TP_Drow_Touch_Point(20,20,RED); //画点1 + TP_Adj_Info_Show(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//显示数据 + continue; + }//正确了 + + //对角线相等 + tem1=abs(pos_temp[1][0]-pos_temp[2][0]);//x1-x3 + tem2=abs(pos_temp[1][1]-pos_temp[2][1]);//y1-y3 + tem1*=tem1; + tem2*=tem2; + d1=sqrt(tem1+tem2);//得到1,4的距离 + + tem1=abs(pos_temp[0][0]-pos_temp[3][0]);//x2-x4 + tem2=abs(pos_temp[0][1]-pos_temp[3][1]);//y2-y4 + tem1*=tem1; + tem2*=tem2; + d2=sqrt(tem1+tem2);//得到2,3的距离 + fac=(float)d1/d2; + if(fac<0.95||fac>1.05)//不合格 + { + cnt=0; + TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,WHITE); //清除点4 + TP_Drow_Touch_Point(20,20,RED); //画点1 + TP_Adj_Info_Show(pos_temp[0][0],pos_temp[0][1],pos_temp[1][0],pos_temp[1][1],pos_temp[2][0],pos_temp[2][1],pos_temp[3][0],pos_temp[3][1],fac*100);//显示数据 + continue; + }//正确了 + //计算结果 + tp_dev.xfac=(float)(lcddev.width-40)/(pos_temp[1][0]-pos_temp[0][0]);//得到xfac + tp_dev.xoff=(lcddev.width-tp_dev.xfac*(pos_temp[1][0]+pos_temp[0][0]))/2;//得到xoff + + tp_dev.yfac=(float)(lcddev.height-40)/(pos_temp[2][1]-pos_temp[0][1]);//得到yfac + tp_dev.yoff=(lcddev.height-tp_dev.yfac*(pos_temp[2][1]+pos_temp[0][1]))/2;//得到yoff + if(abs(tp_dev.xfac)>2||abs(tp_dev.yfac)>2)//触屏和预设的相反了. + { + cnt=0; + TP_Drow_Touch_Point(lcddev.width-20,lcddev.height-20,WHITE); //清除点4 + TP_Drow_Touch_Point(20,20,RED); //画点1 + LCD_ShowString(40,26,lcddev.width,lcddev.height,16,"TP Need readjust!"); + tp_dev.touchtype=!tp_dev.touchtype;//修改触屏类型. + if(tp_dev.touchtype)//X,Y方向与屏幕相反 + { + CMD_RDX=0X90; + CMD_RDY=0XD0; + }else //X,Y方向与屏幕相同 + { + CMD_RDX=0XD0; + CMD_RDY=0X90; + } + continue; + } + POINT_COLOR=BLUE; + LCD_Clear(WHITE);//清屏 + LCD_ShowString(35,110,lcddev.width,lcddev.height,16,"Touch Screen Adjust OK!");//校正完成 + delay_ms(1000); + LCD_Clear(WHITE);//清屏 + return;//校正完成 + } + } + delay_ms(10); + outtime++; + if(outtime>1000) + { + TP_Get_Adjdata(); + break; + } + } +} +//触摸屏初始化 +//返回值:0,没有进行校准 +// 1,进行过校准 +u8 TP_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOB,C,F时钟 + + //GPIOB1,2初始化设置 + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;//PB1/PB2 设置为上拉输入 + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//输入模式 + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出 + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉 + GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化 + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//PB0设置为推挽输出 + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//输出模式 + GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化 + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;//PC13设置为推挽输出 + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//输出模式 + GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化 + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//PF11设置推挽输出 + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//输出模式 + GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化 + + TP_Get_Adjdata(); + return 0; +} + +void UI_Create(u16 x,u16 y,u16 sx,u16 sy,u8 *p,u8 num)//默认16号字体 +{ + LCD_DrawRectangle(x,y,sx,sy); +// if(num*816) +// LCD_ShowString(x+((sx-x)-num*8)/2,y+((sy-y)-16)/2,sx-x,sy-y,16,p);//16号字体 + if(num*612) + LCD_ShowString(x+((sx-x)-num*6)/2,y+((sy-y)-12)/2,sx-x,sy-y,12,p);//12号 +} + +u8 Touch_Scan(void) +{ + static u8 touch_flag=1; + if(tp_dev.scan(0)) + { + if(touch_flag==1) + { + touch_flag=0; + if(00x4 ARM-ADS - 8000000 + 168000000 1 1 @@ -81,38 +81,38 @@ 0 - User Manual (MCBSTM32F400) - D:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.5.0\MDK/Boards/Keil/MCBSTM32F400/Documentation/mcbstm32f200.chm + Getting Started (STM32F4-Discovery) + F:\STM32F103Mini\MDK5\ARM\PACK\Keil\STM32F4xx_DFP\1.0.8\Documents\DM00037368.pdf 1 - Schematics (MCBSTM32F400) - D:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.5.0\MDK/Boards/Keil/MCBSTM32F400/Documentation/mcbstm32f400-schematics.pdf + User Manual (STM32F4-Discovery) + F:\STM32F103Mini\MDK5\ARM\PACK\Keil\STM32F4xx_DFP\1.0.8\Documents\DM00039084.pdf 2 - Getting Started (STM32F4-Discovery) - D:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.5.0\MDK/Boards/ST/STM32F4-Discovery/Documentation/DM00037368.pdf + User Manual (MCBSTM32F400) + F:\STM32F103Mini\MDK5\ARM\PACK\Keil\STM32F4xx_DFP\1.0.8\Documents\mcbstm32f200.chm 3 - User Manual (STM32F4-Discovery) - D:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.5.0\MDK/Boards/ST/STM32F4-Discovery/Documentation/DM00039084.pdf + Schematics (MCBSTM32F400) + F:\STM32F103Mini\MDK5\ARM\PACK\Keil\STM32F4xx_DFP\1.0.8\Documents\mcbstm32f400-schematics.pdf 4 Bill of Materials (STM32F4-Discovery) - D:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.5.0\MDK/Boards/ST/STM32F4-Discovery/Documentation/stm32f4discovery_bom.zip + F:\STM32F103Mini\MDK5\ARM\PACK\Keil\STM32F4xx_DFP\1.0.8\Documents\stm32f4discovery_bom.zip 5 Gerber Files (STM32F4-Discovery) - D:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.5.0\MDK/Boards/ST/STM32F4-Discovery/Documentation/stm32f4discovery_gerber.zip + F:\STM32F103Mini\MDK5\ARM\PACK\Keil\STM32F4xx_DFP\1.0.8\Documents\stm32f4discovery_gerber.zip 6 Schematics (STM32F4-Discovery) - D:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.5.0\MDK/Boards/ST/STM32F4-Discovery/Documentation/stm32f4discovery_sch.zip + F:\STM32F103Mini\MDK5\ARM\PACK\Keil\STM32F4xx_DFP\1.0.8\Documents\stm32f4discovery_sch.zip 7 @@ -147,7 +147,7 @@ 1 0 0 - 6 + 11 @@ -158,33 +158,13 @@ - Segger\JL2CM3.dll + STLink\ST-LINKIII-KEIL_SWO.dll 0 - DLGUARM - - - - 0 - ARMRTXEVENTFLAGS - -L70 -Z18 -C0 -M0 -T1 - - - 0 - DLGTARM - (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0) - - - 0 - ARMDBGFLAGS - - - - 0 - JL2CM3 - -U4294967295 -O78 -S1 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32F4xx_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32F407ZG$CMSIS/Flash/STM32F4xx_1024.FLM) + ST-LINKIII-KEIL_SWO + -U303030303030303030303031 -I0 -O206 -S1 -C0 -A0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32F4xx_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32F407ZG$Flash\STM32F4xx_1024.FLM) 0 @@ -193,28 +173,6 @@ - - - 0 - 2 - Adresult - - - 1 - 2 - buf,0x0A - - - 2 - 2 - Vpp_buff - - - 3 - 2 - Ypos2,0x0A - - 0 @@ -226,7 +184,7 @@ 0 0 0 - 1 + 0 0 0 0 @@ -246,16 +204,6 @@ - - - System Viewer\ADC1 - 35904 - - - System Viewer\DMA2 - 35905 - - @@ -359,8 +307,8 @@ 0 0 0 - ..\HARDWARE\DAC\dac.c - dac.c + ..\HARDWARE\ADC\adc.c + adc.c 0 0 @@ -372,8 +320,8 @@ 0 0 0 - ..\HARDWARE\ADC\adc.c - adc.c + ..\HARDWARE\TIMER\timer.c + timer.c 0 0 @@ -385,8 +333,8 @@ 0 0 0 - ..\HARDWARE\TIMER\timer.c - timer.c + ..\HARDWARE\KEY\key.c + key.c 0 0 @@ -394,7 +342,7 @@ SYSTEM - 1 + 0 0 0 0 @@ -441,7 +389,7 @@ CORE - 1 + 0 0 0 0 @@ -462,7 +410,7 @@ FWLIB - 1 + 0 0 0 0 diff --git a/USER/LCD.uvprojx b/USER/LCD.uvprojx index 6736617..399eab1 100644 --- a/USER/LCD.uvprojx +++ b/USER/LCD.uvprojx @@ -14,7 +14,7 @@ STM32F407ZG STMicroelectronics - Keil.STM32F4xx_DFP.2.5.0 + Keil.STM32F4xx_DFP.1.0.8 http://www.keil.com/pack IROM(0x08000000,0x100000) IRAM(0x20000000,0x20000) IRAM2(0x10000000,0x10000) CPUTYPE("Cortex-M4") FPU2 CLOCK(168000000) ELITTLE @@ -147,7 +147,7 @@ 1 0 - 6 + 11 @@ -161,7 +161,7 @@ - Segger\JL2CM3.dll + STLink\ST-LINKIII-KEIL_SWO.dll @@ -365,7 +365,7 @@ STM32F40_41xxx,USE_STDPERIPH_DRIVER - ..\CORE;..\SYSTEM\delay;..\SYSTEM\sys;..\SYSTEM\usart;..\USER;..\HARDWARE\LED;..\HARDWARE\LCD;..\FWLIB\inc;..\HARDWARE\ADC;..\HARDWARE\DAC;..\HARDWARE\TIMER + ..\CORE;..\SYSTEM\delay;..\SYSTEM\sys;..\SYSTEM\usart;..\USER;..\HARDWARE\LED;..\HARDWARE\LCD;..\FWLIB\inc;..\HARDWARE\ADC;..\HARDWARE\TIMER;..\HARDWARE\TOUCH;..\HARDWARE\KEY @@ -443,11 +443,6 @@ 1 ..\HARDWARE\LCD\lcd.c - - dac.c - 1 - ..\HARDWARE\DAC\dac.c - adc.c 1 @@ -458,6 +453,11 @@ 1 ..\HARDWARE\TIMER\timer.c + + key.c + 1 + ..\HARDWARE\KEY\key.c + diff --git a/USER/main.c b/USER/main.c index cc2d00b..1eecc50 100644 --- a/USER/main.c +++ b/USER/main.c @@ -1,75 +1,149 @@ + //STM32 使用DMA+DAC+TIMER输出正弦波// + +/* + + 那么对于使用DMA+DAC+TIMER产生正弦波的原理或过程,我有这样一个简单的理解: + 先将一个可以生成正弦波的数据表保存在静态内存中,然后在DAC以及这块内存中间使 + 用DMA建立一个通道,经过以上步骤之后,DAC模块就可以通过DMA通道拿取静态内存中 + 可以生成正弦波的数据,拿取数据,然后经过数模准换,在引脚进行输出就可以得到正 + 弦波了。那么当然,这个速度是非常快的,如果没有一定的延时,那么得到的估计就是 + 一个变化很快的模拟量。所以这个时候就需要使用定时器TIMER了。DAC在初始化的时候, + 可以设置成使用定时器触发,这就意味着,当定时器溢满的时候,就会触发DAC工作。 + 这样一来,就可以通过改变定时器的定时时间来改变正弦波的周期了。 + + 电压大小的显示用DAC来处理 +*/ + #include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "lcd.h" -#include "dac.h" +//#include "dac.h" #include "adc.h" #include "waveform.h" #include "timer.h" #include "stm32f4xx_it.h" -//ALIENTEK 探索者STM32F407开发板 实验13 -//LCD显示实验-库函数版本 -//技术支持:www.openedv.com -//淘宝店铺:http://eboard.taobao.com -//广州市星翼电子科技有限公司 -//作者:正点原子 @ALIENTEK - - +#include "key.h" +#include "stm32f4xx.h" // Device header +//void touch_task(void); //触摸功能,可添加,这里只有TFTLCD所以不用 void clear_point(u16 num);//更新显示屏当前列 void Set_BackGround(void);//设置背景 void Lcd_DrawNetwork(void);//画网格 float get_vpp(u16 *buf);//获取峰峰值 -void DrawOscillogram(u16* buf);//画波形图 +void DrawOscillogram(u16* buf);//画波形图 + +void sin_Generation(void); +void sawtooth_Generation(void); +void triangle_Generation(void); +void rectangle_Generation(void); + + u32 max_data; + u16 position=140;//波形图中心轴 + u8 num=0; + u8 runstop=1; + int main(void) { u16 buff[800]; float Adresult = 0; u8 Vpp_buff[20] = {0}; + u8 key=0; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2 delay_init(168); //初始化延时函数 uart_init(115200); //初始化串口波特率为115200 LED_Init(); //初始化LED LCD_Init(); //初始化LCD FSMC接口 - Adc_Init(); //初始化ADC + Adc_Init(); //初始化ADC Set_BackGround(); //显示背景 Lcd_DrawNetwork(); - MYDAC_Init(); //产生正弦波 + KEY_Init(); LED0 = 0; + MYDAC_Init(); - while(1) - { - DrawOscillogram(buff);//画波形 - Adresult = get_vpp(buff);//峰峰值mv - sprintf((char*)Vpp_buff,"Vpp = %0.3fV",Adresult); - POINT_COLOR = WHITE; - BACK_COLOR = DARKBLUE; - LCD_ShowString(330,425,210,24,24,Vpp_buff); - LED0 = !LED0; - } + + while(1) + + { + //void touch_task(void); + DrawOscillogram(buff);//画波形 + Adresult = get_vpp(buff);//峰峰值mv + sprintf((char*)Vpp_buff,"Vpp = %0.3fV",Adresult); + POINT_COLOR = WHITE; + BACK_COLOR = BLACK; + LCD_ShowString(156,201,66,12,12,Vpp_buff); + //runstop=KEY_Scan(0); +// if(runstop==1){ + POINT_COLOR = WHITE; + LCD_ShowString(258,0,288,29,12,"STOP"); + POINT_COLOR = YELLOW; + LCD_ShowString(289,0,319,29,12,"RUN"); + LED0 = !LED0;//} +//else if(runstop==0) +//{ +// POINT_COLOR = YELLOW; +// LCD_ShowString(258,0,288,29,12,"STOP"); +// LCD_ShowString(289,0,319,29,12,"RUN"); +//} + + key=KEY_Scan(0); //得到键值 + if(key) + { + switch(key) + { + case WKUP_PRES: //控制蜂鸣器 + sin_Generation(); + break; +// case KEY0_PRES: //控制LED0翻转 +// runstop=0; +// break; + case KEY1_PRES: //控制LED1翻转 + triangle_Generation(); + break; + case KEY2_PRES: //同时控制LED0,LED1翻转 + sawtooth_Generation(); + break; + } + } + else if(key == 0) + { + do + { + //runstop=0; + //void DrawOscillogram(u16* buf); + POINT_COLOR = YELLOW; + LCD_ShowString(258,0,288,29,12,"STOP"); + POINT_COLOR = WHITE; + LCD_ShowString(289,0,319,29,12,"RUN"); + key=KEY_Scan(0); + if(key==0||key==2||key==3||key==4)break; + }while(1); + + } + } } void clear_point(u16 num)//更新显示屏当前列 { - u16 index_clear_lie = 0; - POINT_COLOR = DARKBLUE ; - for(index_clear_lie = 1;index_clear_lie < 400;index_clear_lie++) + u16 lie = 0; + POINT_COLOR = BLACK ; + for(lie = 1;lie < 199;lie++) { - LCD_DrawPoint(num,index_clear_lie ); + LCD_DrawPoint(num,lie ); } if(!(num%50))//判断hang是否为50的倍数 画列点 { - for(index_clear_lie = 10;index_clear_lie < 400;index_clear_lie += 10) + for(lie = 10;lie < 199;lie += 10) { - LCD_Fast_DrawPoint(num ,index_clear_lie,WHITE ); + LCD_Fast_DrawPoint(num ,lie,WHITE ); } } if(!(num%10))//判断hang是否为10的倍数 画行点 { - for(index_clear_lie = 50;index_clear_lie <400;index_clear_lie += 50) + for(lie = 50;lie <199;lie += 50) { - LCD_Fast_DrawPoint(num ,index_clear_lie,WHITE ); + LCD_Fast_DrawPoint(num ,lie,WHITE ); } } POINT_COLOR = YELLOW; @@ -77,56 +151,107 @@ int main(void) void DrawOscillogram(u16 *buff)//画波形图 { - static u16 Ypos1 = 0,Ypos2 = 0; - u16 Yinit=100; - u16 i = 0; - POINT_COLOR = YELLOW; - for(i = 1;i < 700;i++)//存储AD数值 - { - buff[i] = Get_Adc(ADC_Channel_5); - } - for(i = 1;i < 700;i++) - { - clear_point(i ); - Ypos2 = 400 - (Yinit + buff[i] * 165 / 4096);//转换坐标 - //Ypos2 = Ypos2 * bei; - if(Ypos2 >700) - Ypos2 =700; //超出范围不显示 - LCD_DrawLine (i ,Ypos1 , i+1 ,Ypos2); - Ypos1 = Ypos2 ; - } + runstop = KEY_Scan(0); + + if(runstop==1|runstop==2|runstop==3|runstop==4)//画正弦波 + { + static u16 Ypos1 = 0,Ypos2 = 0; + u16 i = 0; + for(i = 1;i < 255;i++)//存储AD数值 + { + buff[i]=Get_Adc(ADC_Channel_5); +// delay_us(1); + } + for(i = 1;i < 255;i++) + { + clear_point(i); + Ypos2 = position - ( buff[i] * 165 / 4096);//转换坐标//4096 + if(Ypos2 >255) + Ypos2 =255; //超出范围不显示 + LCD_DrawLine (i ,Ypos1 , i+1 ,Ypos2);//波形连接 + Ypos1 = Ypos2 ; + } Ypos1 = 0; -} + } + +// else if(runstop==0)//暂停动态显示 +// { +// do +// { +//// u8 a=0; +// runstop = KEY_Scan(0); +// POINT_COLOR = YELLOW; +// LCD_ShowString(258,0,288,29,12,"STOP"); +// POINT_COLOR = WHITE; +// LCD_ShowString(289,0,319,29,12,"RUN"); +// //runstop=1; +// if( runstop == 2|runstop==3|runstop==4 ) break; +// } +// while(1); +// } + + else if(runstop==2) + { +// static u16 Ypos1 = 0,Ypos2 = 0; +// u16 i = 0; +// for(i = 1;i < 255;i++)//存储AD数值 +// { +// buff[i]=Get_Adc(ADC_Channel_5); +//// delay_us(1); +// } +// for(i = 1;i < 255;i++) +// { +// clear_point(i); +// Ypos2 = position - ( buff[i] * 165 / 4096);//转换坐标//4096 +// if(Ypos2 >255) +// Ypos2 =255; //超出范围不显示 +// LCD_DrawLine (i ,Ypos1 , i+1 ,Ypos2);//波形连接 +// Ypos1 = Ypos2 ; +// } +// Ypos1 = 0; + } + + else if(runstop==3) + { + + } + + else if(runstop==4) + { + + } +} void Set_BackGround(void) { - POINT_COLOR = YELLOW; - LCD_Clear(DARKBLUE); - LCD_DrawRectangle(0,0,700,400);//矩形 - //LCD_DrawLine(0,220,700,220);//横线 - //LCD_DrawLine(350,20,350,420);//竖线 - //POINT_COLOR = WHITE; - //BACK_COLOR = DARKBLUE; - //LCD_ShowString(330,425,210,24,24,(u8*)"vpp="); + LCD_Clear(BLACK); + POINT_COLOR = WHITE; + LCD_DrawRectangle(0,0,257,200); +// POINT_COLOR = WHITE; +// LCD_ShowString(258,0,288,29,12,"STOP"); +// LCD_ShowString(289,0,319,29,12,"RUN"); } void Lcd_DrawNetwork(void) { u16 index_y = 0; u16 index_x = 0; - + POINT_COLOR = WHITE; + LCD_DrawRectangle(258,0,288,29); + POINT_COLOR = WHITE; + LCD_DrawRectangle(289,0,319,29); //画列点 - for(index_x = 50;index_x < 700;index_x += 50) + for(index_x = 50;index_x < 255;index_x += 50) { - for(index_y = 10;index_y < 400;index_y += 10) + for(index_y = 10;index_y < 199;index_y += 10) { LCD_Fast_DrawPoint(index_x,index_y,WHITE); } } //画行点 - for(index_y = 50;index_y < 400;index_y += 50) + for(index_y = 50;index_y < 199;index_y += 50) { - for(index_x = 10;index_x < 700;index_x += 10) + for(index_x = 10;index_x < 255;index_x += 10) { LCD_Fast_DrawPoint(index_x,index_y,WHITE); } @@ -136,23 +261,27 @@ void Lcd_DrawNetwork(void) float get_vpp(u16 *buf) //获取峰峰值 { - u32 max_data=buf[1]; - u32 min_data=0;//buf[1]; + u32 max_data=buf[0]; + u32 min_data=buf[0]; u32 n=0; float Vpp=0; - for(n = 1;n<700;n++) + for(n = 1;n<256;n++) { if(buf[n] > max_data) { max_data = buf[n]; - } -// if(buf[n] < min_data) -// { -// min_data = buf[n]; -// } + } + else if(buf[n] < min_data) + min_data = buf[n]; } Vpp = (float)(max_data - min_data); Vpp = Vpp*(3.3/4096); + max_data = max_data*(3.3/4096); + min_data = min_data*(3.3/4096); return Vpp; } + + + + diff --git a/USER/stm32f4xx_it.c b/USER/stm32f4xx_it.c index b1f8b02..3708c0d 100644 --- a/USER/stm32f4xx_it.c +++ b/USER/stm32f4xx_it.c @@ -34,7 +34,7 @@ #include "usart.h" #include "led.h" #include "lcd.h" -#include "dac.h" +//#include "dac.h" #include "adc.h" #include "waveform.h" #include "timer.h" diff --git a/USER/waveform.c b/USER/waveform.c index 5aac0fa..5df1c80 100644 --- a/USER/waveform.c +++ b/USER/waveform.c @@ -1,68 +1,147 @@ -#include "dac.h" + //STM32 使用DMA+DAC+TIMER输出正弦波// + +/* + + 那么对于使用DMA+DAC+TIMER产生正弦波的原理或过程,我有这样一个简单的理解: + 先将一个可以生成正弦波的数据表保存在静态内存中,然后在DAC以及这块内存中间使 + 用DMA建立一个通道,经过以上步骤之后,DAC模块就可以通过DMA通道拿取静态内存中 + 可以生成正弦波的数据,拿取数据,然后经过数模准换,在引脚进行输出就可以得到正 + 弦波了。那么当然,这个速度是非常快的,如果没有一定的延时,那么得到的估计就是 + 一个变化很快的模拟量。所以这个时候就需要使用定时器TIMER了。DAC在初始化的时候, + 可以设置成使用定时器触发,这就意味着,当定时器溢满的时候,就会触发DAC工作。 + 这样一来,就可以通过改变定时器的定时时间来改变正弦波的周期了。 + + 电压大小的显示用DAC来处理 +*/ + + +//#include "dac.h" #include "sys.h" #include "math.h" #include "waveform.h" +#include "key.h" +#include "delay.h" #define PI 3.14159 #define DAC_DHR12R1_ADDRESS 0x40007408 -u16 sinTable[tableSize]; +u16 sinTable[tableSize];//256; +//u16 sawtoothTable[tableSize];//256; +//u16 triangleTable[tableSize];//256; +//u16 rectangleTable[tableSize];//256; +u8 KEY_Scan(u8 mode); + +//将正弦波数据保存在静态内存中 void sin_Generation(void) { u16 n; + u16 temp=1023; + //temp=KEY_Scan(0); + if(KEY_Scan(0) == 4) + { + temp=temp+200; + } for(n=0;n