本帖最后由 小小电子爱好者 于 2019-6-28 18:59 编辑
代码部分:
DAC部分代码static void DMA_Config(void)
{
DMA_GlobalDeInit();
DMA_DeInit(DMA1_Channel3);
CLK_PeripheralClockConfig(CLK_Peripheral_DMA1, ENABLE);
DMA_Init(DMA1_Channel3,
(uint32_t)((uint16_t)&Wave_Buffer),
0x5388,
130,
DMA_DIR_MemoryToPeripheral,
DMA_Mode_Circular,
DMA_MemoryIncMode_Inc,
DMA_Priority_VeryHigh,
DMA_MemoryDataSize_HalfWord );
DMA_Cmd(DMA1_Channel3, ENABLE);
DMA_GlobalCmd(ENABLE );
}
static void Timer4_Config()
{
TIM4_DeInit();
CLK_PeripheralClockConfig(CLK_Peripheral_TIM4, ENABLE);
TIM4_TimeBaseInit(TIM4_Prescaler_1,
0x09);
TIM4_SelectOutputTrigger(TIM4_TRGOSource_Update);
//TIM4_ITConfig( TIM4_IT_Update, ENABLE );
TIM4_Cmd(ENABLE);
}
/**
*
* DAC初始化
*
**/
void DAC_Config()
{
DAC_DeInit();
CLK_PeripheralClockConfig(CLK_Peripheral_DAC, ENABLE);
DAC_Init(DAC_Channel_1,
DAC_Trigger_T4_TRGO,//DAC_Trigger_Software//DAC_Trigger_T4_TRGO
DAC_OutputBuffer_Disable);//DAC_OutputBuffer_Enable
DAC_Cmd(DAC_Channel_1, ENABLE);
DAC_DMACmd(DAC_Channel_1, ENABLE);
Timer4_Config();
DMA_Config();
}
编码器部分
void ROTATY_Init()
{
GPIO_Init(GPIOD,GPIO_Pin_7|GPIO_Pin_6|GPIO_Pin_5,GPIO_Mode_In_PU_No_IT);
}
void ROTATY_Scan_Driver()
{
static uint8_t Turn_L=0,Turn_R=0,Rot_Flag=0;
if((GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_7)==GPIO_Pin_7)&&(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_6)==GPIO_Pin_6))
{
Rot_Flag=0x01;
}
if(Rot_Flag == 0x01)
{
if((GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_7)!=GPIO_Pin_7)&&(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_6)!=GPIO_Pin_6))
{
if(Turn_L == 0x01)
{
if((Selet_Value == 0x00)&&(Menu_value == 0))
{
if(Roty_Value<4000)
Roty_Value+=Roty_Value2;
Roty_value3=(uint16_t)((Roty_Value*3.3)*10/4096);
OLED_ShowNum(80,6,Roty_value3/10,1,16);
OLED_ShowChar(88,6,'.');
OLED_ShowNum(96,6,Roty_value3%10,1,16);
}
else if((Selet_Value == 0x01)&&(Menu_value == 0))
{
if(Bias_Value<9)
Bias_Value+=Bias_Value2;
OLED_ShowNum(0,6,Bias_Value*1000,5,16);
TIM4_TimeBaseInit(Bias_Value,10);
}
Rot_Flag=0x00;
}
if(Turn_R == 0x01)
{
if((Selet_Value == 0x00)&&(Menu_value == 0))
{
if(Roty_Value>100)
Roty_Value-=Roty_Value2;
Roty_value3=(uint16_t)((Roty_Value*3.3)*10/4096);
OLED_ShowNum(80,6,Roty_value3/10,1,16);
OLED_ShowChar(88,6,'.');
OLED_ShowNum(96,6,Roty_value3%10,1,16);
}
else if((Selet_Value == 0x01)&&(Menu_value == 0))
{
if(Bias_Value>1)
Bias_Value-=Bias_Value2;
OLED_ShowNum(0,6,Bias_Value*1000,5,16);
TIM4_TimeBaseInit(Bias_Value,10);
}
Rot_Flag=0x00;
}
if(Menu_value == 0)
{
if(n_wave == 1)
getSinTab(130,Roty_Value);
else if(n_wave == 2)
getTriaTab(130,Roty_Value);
else if(n_wave == 3)
getSawTab(130,Roty_Value);
else if(n_wave == 4)
getSquarTab(130,Roty_Value);
}
}
}
if((GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_7) == GPIO_Pin_7))
{
Turn_L =0x01;
}
else
{
Turn_L =0;
}
if((GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_6) == GPIO_Pin_6))
{
Turn_R =0x01;
}
else
{
Turn_R =0;
}
}
OLED部分
void Delay_5us()
{
uint8_t i,x;
for(i = 0;i>45;x++)
{
}
}
void iic_start()
{
GPIO_WriteBit( GPIOB, IIC_DAT,SET);
GPIO_WriteBit( GPIOB, IIC_CLK,SET);
Delay_5us();
GPIO_WriteBit( GPIOB, IIC_DAT,RESET);
GPIO_WriteBit( GPIOB, IIC_CLK,RESET);
Delay_5us();
}
void iic_stop()
{
GPIO_WriteBit( GPIOB, IIC_DAT,RESET);
GPIO_WriteBit( GPIOB, IIC_CLK,SET);
Delay_5us();
GPIO_WriteBit( GPIOB, IIC_DAT,SET);
}
uint8_t iic_ReadByte(void)
{
uint8_t i;
uint8_t value;
/* 读到第1个bit为数据的bit7 */
value = 0;
GPIO_Init( GPIOB, IIC_DAT, GPIO_Mode_In_FL_No_IT);
for (i = 0; i < 8; i++)
{
value <<= 1;
GPIO_WriteBit( GPIOB, IIC_CLK,SET);
Delay_5us();
if (GPIO_ReadInputDataBit( GPIOB, IIC_DAT) ==IIC_DAT)
{
value++;
}
GPIO_WriteBit( GPIOB, IIC_CLK,RESET);
Delay_5us();
}
GPIO_Init( GPIOB, IIC_DAT, GPIO_Mode_Out_PP_High_Fast);
GPIO_WriteBit( GPIOB, IIC_DAT,SET);
return value;
}
uint8_t iic_waitAck()
{
uint8_t res=1;
uint8_t i=0;
GPIO_WriteBit( GPIOB, IIC_CLK,SET);
Delay_5us();
GPIO_Init( GPIOB, IIC_DAT, GPIO_Mode_In_FL_No_IT);
while((res)&&(i<5))
{
if(GPIO_ReadInputDataBit( GPIOB, IIC_DAT) ==IIC_DAT )
{
res = 1;
}
else
{
res= 0;
}
i++;
}
GPIO_WriteBit( GPIOB, IIC_CLK,RESET);
GPIO_Init( GPIOB, IIC_DAT, GPIO_Mode_Out_PP_High_Fast);
return res;
}
void iic_rack()
{
GPIO_Init( GPIOB, IIC_DAT, GPIO_Mode_Out_PP_High_Fast);
GPIO_WriteBit( GPIOB, IIC_DAT,RESET);
Delay_5us();
GPIO_WriteBit( GPIOB, IIC_CLK,SET);
Delay_5us();
GPIO_WriteBit( GPIOB, IIC_CLK,RESET);
Delay_5us();
GPIO_WriteBit( GPIOB, IIC_DAT,SET);
}
void iic_nack()
{
GPIO_Init( GPIOB, IIC_DAT, GPIO_Mode_Out_PP_High_Fast);
GPIO_WriteBit( GPIOB, IIC_DAT,SET);
Delay_5us();
GPIO_WriteBit( GPIOB, IIC_CLK,SET);
Delay_5us();
GPIO_WriteBit( GPIOB, IIC_CLK,RESET);
Delay_5us();
}
uint8_t iic_sendbyte(uint8_t data)
{
uint8_t i;
for(i=0;i<8;i++)
{
if(data & 0x80)
{
GPIO_WriteBit( GPIOB, IIC_DAT,SET);
}
else
{
GPIO_WriteBit( GPIOB, IIC_DAT,RESET);
}
data<<=1;
GPIO_WriteBit( GPIOB, IIC_CLK,SET);
Delay_5us();
GPIO_WriteBit( GPIOB, IIC_CLK,RESET);
Delay_5us();
}
GPIO_WriteBit( GPIOB, IIC_DAT,SET);
return data;
}
/**
* @函数名 Write_OELD_Command
* @功 能 对OLED写入命令
* @参 数 IIC_Command:写入的命令字节
* @返回值 无
*/
void Write_OLED_Command(unsigned char IIC_Command)
{
iic_start();
iic_sendbyte(0x78);
iic_waitAck();
iic_sendbyte(0x00);
iic_waitAck();
iic_sendbyte(IIC_Command);
iic_waitAck();
iic_stop();
}
/**
* @函数名 Write_OELD_Data
* @功 能 对OLED写入数据
* @参 数 IIC_Data:写入的数据字节
* @返回值 无
*/
void Write_OLED_Data(unsigned char IIC_Data)
{
iic_start();
iic_sendbyte(0x78);
iic_waitAck();
iic_sendbyte(0x40);
iic_waitAck();
iic_sendbyte(IIC_Data);
iic_waitAck();
iic_stop();
}
/**
* @函数名 OLED_WR_Byte
* @功 能 OLED写入一字节命令/数据
* @参 数 dat:写入的数据/命令字节
* @返回值 cmd:1-写入数据;0-写入命令
*/
void OLED_WR_Byte(unsigned char dat,unsigned char cmd)
{
if(cmd)
{
Write_OLED_Data(dat); //写入数据
}
else {
Write_OLED_Command(dat); //写入命令
}
}
/**
* @函数名 OLED_Set_Pos
* @功 能 在坐标X,Y初开始花店
* @参 数 x:X坐标;y:Y坐标
* @返回值 无
*/
void OLED_Set_Pos(unsigned char x, unsigned char y)
{
OLED_WR_Byte(0xb0+y,OLED_CMD); //写入页地址
OLED_WR_Byte((x&0x0f),OLED_CMD); //写入列低地址
OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD); //写入列高地址
}
/**
* @函数名 OLED_Display_On
* @功 能 开OLED显示
* @参 数 无
* @返回值 无
*/
void OLED_Display_On(void)
{
OLED_WR_Byte(0X8D,OLED_CMD); //设置OLED电荷泵
OLED_WR_Byte(0X14,OLED_CMD); //使能,开
OLED_WR_Byte(0XAF,OLED_CMD); //开显示
}
/**
* @函数名 OLED_Display_Off
* @功 能 关OLED显示
* @参 数 无
* @返回值 无
*/
void OLED_Display_Off(void)
{
OLED_WR_Byte(0X8D,OLED_CMD); //设置OLED电荷泵
OLED_WR_Byte(0X10,OLED_CMD); //失能,关
OLED_WR_Byte(0XAE,OLED_CMD); //关显示
}
/**
* @函数名 OLED_Clear
* @功 能 清屏
* @参 数 无
* @返回值 无
*/
void OLED_Clear(void)
{
unsigned char i,n; //定义变量
for(i=0;i<8;i++)
{
OLED_WR_Byte (0xb0+i,OLED_CMD); //从0~7页依次写入
OLED_WR_Byte (0x00,OLED_CMD); //列低地址
OLED_WR_Byte (0x10,OLED_CMD); //列高地址
for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA); //写入 0 清屏
}
}
/**
* @函数名 OLED_ShowChar
* @功 能 在指定位置显示字符
* @参 数 x:X坐标;y:Y坐标;chr:显示的字符
* @返回值 无
*/
void OLED_ShowChar(unsigned char x,unsigned char y,unsigned char chr)
{
unsigned char c=0,i=0;
c=chr-' '; //获取字符的偏移量
if(x>Max_Column-1){x=0;y=y+2;} //如果列书超出了范围,就从下2页的第0列开始
if(SIZE ==16) //字符大小如果为 16 = 8*16
{
OLED_Set_Pos(x,y); //从x y 开始画点
for(i=0;i<8;i++) //循环8次 占8列
OLED_WR_Byte(F8X16[c*16+i],OLED_DATA); //找出字符 c 的数组位置,先在第一页把列画完
OLED_Set_Pos(x,y+1); //页数加1
for(i=0;i<8;i++) //循环8次
OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA); //把第二页的列数画完
}
else //字符大小为 6 = 6*8
{
OLED_Set_Pos(x,y+1); //一页就可以画完
for(i=0;i<6;i++) //循环6次 ,占6列
OLED_WR_Byte(F6x8[c][i],OLED_DATA); //把字符画完
}
}
/**
* @函数名 oled_pow
* @功 能 计算m的n次方
* @参 数 无
* @返回值 result:计算结果
*/
unsigned int oled_pow(unsigned char m,unsigned char n)
{
unsigned int result=1;
while(n--)result*=m;
return result;
}
/**
* @函数名 OLED_ShowNum
* @功 能 在指定的位置显示指定长度&大小的数字
* @参 数 x:X坐标;y:Y坐标;num:显示的数字;len:数字的长度;size2:字体的大小
* @返回值 无
*/
void OLED_ShowNum(unsigned char x,unsigned char y,unsigned int num,unsigned char len,unsigned char size2)
{
unsigned char t,temp; //定义变量
unsigned char enshow=0; //定义变量
for(t=0;t<len;t++)
{
temp=(num/oled_pow(10,len-t-1))%10;//取出输入数的每个位,由高到低
if(enshow==0&&t<(len-1)) //enshow:是否为第一个数;t<(len-1):判断是否为最后一个数
{
if(temp==0) //如果该数为0
{
OLED_ShowChar(x+(size2/2)*t,y,' ');//显示 0 ;x+(size2/2)*t根据字体大小偏移的列数(8)
continue; //跳过剩下语句,继续重复循环(避免重复显示)
}else enshow=1;
}
OLED_ShowChar(x+(size2/2)*t,y,temp+'0'); //显示一个位;x+(size2/2)*t根据字体大小偏移的列数(8)
}
}
/**
* @函数名 OLED_ShowString
* @功 能 在指定位置显示字符串
* @参 数 x:X坐标;y:Y坐标;*chr:显示的字符串
* @返回值 无
*/
void OLED_ShowString(unsigned char x,unsigned char y,unsigned char *chr)
{
unsigned char j=0; //定义变量
while (chr[j]!='\0') //如果不是最后一个字符
{
OLED_ShowChar(x,y,chr[j]); //显示字符
x+=8; //列数加8 ,一个字符的列数占8
if(x>120){x=0;y+=2;} //如果x超过128,切换页,从该页的第一列显示
j++; //下一个字符
}
}
/**
* @函数名 OLED_ShowCHinese
* @功 能 在指定的位置显示汉字
* @参 数 x:X坐标;y:Y坐标;no:汉字的数组位置
* @返回值 无
*/
void OLED_ShowCHinese(unsigned char x,unsigned char y,unsigned char no)
{
unsigned char t; //定义变量
OLED_Set_Pos(x,y); //从 x y 开始画点,先画第一页
for(t=0;t<16;t++) //循环16次,画第一页的16列
{
OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);//画no在数组位置的第一页16列的点
}
OLED_Set_Pos(x,y+1); //画第二列
for(t=0;t<16;t++) //循环16次,画第二页的16列
{
OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);//画no在数组位置的第二页16列的点
}
}
/**
* @函数名 OLED_DrawBMP
* @功 能 在指定的范围显示图片
* @参 数 x0:起始X坐标;y0:起始X坐标;x1:起始X坐标;y1:起始X坐标;BMP[]:图片的数组起始地址
* @返回值 无
*/
void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[])
{
unsigned int j=0; //定义变量
unsigned char x,y; //定义变量
if(y1%8==0) y=y1/8; //判断终止页是否为8的整数倍
else y=y1/8+1;
for(y=y0;y<y1;y++) //从起始页开始,画到终止页
{
OLED_Set_Pos(x0,y); //在页的起始列开始画
for(x=x0;x<x1;x++) //画x1 - x0 列
{
OLED_WR_Byte(BMP[j++],OLED_DATA); //画图片的点
}
}
}
/**
* @函数名 OLED_Init
* @功 能 OLED初始化
* @参 数 无
* @返回值 无
*/
void OLED_Init(void)
{
delay_ms(200); //延迟,由于单片机上电初始化比OLED快,所以必须加上延迟,等待OLED上电初始化完成
OLED_WR_Byte(0xAE,OLED_CMD); //关闭显示
OLED_WR_Byte(0x2e,OLED_CMD); //关闭滚动
OLED_WR_Byte(0x00,OLED_CMD); //设置低列地址
OLED_WR_Byte(0x10,OLED_CMD); //设置高列地址
OLED_WR_Byte(0x40,OLED_CMD); //设置起始行地址
OLED_WR_Byte(0xB0,OLED_CMD); //设置页地址
OLED_WR_Byte(0x81,OLED_CMD); // 对比度设置,可设置亮度
OLED_WR_Byte(0xFF,OLED_CMD); // 265
OLED_WR_Byte(0xA1,OLED_CMD); //设置段(SEG)的起始映射地址;column的127地址是SEG0的地址
OLED_WR_Byte(0xA6,OLED_CMD); //正常显示;0xa7逆显示
OLED_WR_Byte(0xA8,OLED_CMD); //设置驱动路数
OLED_WR_Byte(0x3F,OLED_CMD); //1/32 duty
OLED_WR_Byte(0xC8,OLED_CMD); //重映射模式,COM[N-1]~COM0扫描
OLED_WR_Byte(0xD3,OLED_CMD); //设置显示偏移
OLED_WR_Byte(0x00,OLED_CMD); //无偏移
OLED_WR_Byte(0xD5,OLED_CMD); //设置震荡器分频(默认)大概370KHz
OLED_WR_Byte(0x80,OLED_CMD);
OLED_WR_Byte(0xD8,OLED_CMD); //设置 area color mode off(没有)
OLED_WR_Byte(0x05,OLED_CMD);
OLED_WR_Byte(0xD9,OLED_CMD); //设置 Pre-Charge Period(默认)
OLED_WR_Byte(0xF1,OLED_CMD);
OLED_WR_Byte(0xDA,OLED_CMD); //设置 com pin configuartion(默认)
OLED_WR_Byte(0x12,OLED_CMD);
OLED_WR_Byte(0xDB,OLED_CMD); //设置 Vcomh,可调节亮度(默认)
OLED_WR_Byte(0x30,OLED_CMD);
OLED_WR_Byte(0x8D,OLED_CMD); //设置OLED电荷泵
OLED_WR_Byte(0x14,OLED_CMD); //开显示
OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)
OLED_WR_Byte(0xAF,OLED_CMD);//开启OLED面板显示
OLED_Clear(); //清屏
OLED_Set_Pos(0,0); //画点
}
/**
* @函数名 OLED_Scroll
* @功 能 滚动效果配置函数
* @参 数 无
* @返回值 无
*/
void OLED_Scroll(void)
{
OLED_WR_Byte(0x2E,OLED_CMD); //关闭滚动
OLED_WR_Byte(0x27,OLED_CMD); //水平向左滚动
OLED_WR_Byte(0x00,OLED_CMD); //虚拟字节
OLED_WR_Byte(0x00,OLED_CMD); //起始页 0
OLED_WR_Byte(0x00,OLED_CMD); //滚动时间间隔
OLED_WR_Byte(0x01,OLED_CMD); //终止页 1
OLED_WR_Byte(0x00,OLED_CMD); //虚拟字节
OLED_WR_Byte(0xFF,OLED_CMD); //虚拟字节
OLED_WR_Byte(0x2F,OLED_CMD); //开启滚动
}
|
来了,老弟
@LED2013 :来了
你的主贴呢
积极参与