> 文档中心 > 【GD32F310开发板试用】GD32F310定时器采样MP6050并在彩色LCD上显示波形

【GD32F310开发板试用】GD32F310定时器采样MP6050并在彩色LCD上显示波形


首发极术社区。如对兆易创新GD32F310 MCU感兴趣,欢迎添加微信 aijishu2020 加入GD32技术讨论群。

1.开发环境

(1)IAR8.4
(2)MPU6050 1.8寸显示屏

2.软件

(1)MPU6050陀螺仪驱动
i2C配置:

void i2c0_gpio_config(void){rcu_periph_clock_enable(RCU_GPIOB);rcu_periph_clock_enable(RCU_I2C0);  gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_6);gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_7);gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_6);gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6);gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_7);gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_7);}void i2c_config(void){i2c_clock_config(I2C0, 200000, I2C_DTCY_2);i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE,     I2C_ADDFORMAT_7BITS, SlaveAddress);i2c_enable(I2C0);i2c_ack_config(I2C0, I2C_ACK_ENABLE);}uint8_t Read_Byte(uint16_t SlaveAddr,uint16_t ReadAddr, uint8_t *DataByte){uint8_t err = 1;i2c_start_on_bus(I2C0);while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND));    i2c_master_addressing(I2C0, SlaveAddr<<1, I2C_TRANSMITTER); while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND));    i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);     while(!i2c_flag_get(I2C0, I2C_FLAG_TBE)); i2c_data_transmit(I2C0, ReadAddr);    while(!i2c_flag_get(I2C0, I2C_FLAG_TBE));    i2c_start_on_bus(I2C0);while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND));    i2c_master_addressing(I2C0, SlaveAddr<<1, I2C_RECEIVER);     while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND));    i2c_ack_config(I2C0, I2C_ACK_DISABLE);     i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);     i2c_stop_on_bus(I2C0);while(!i2c_flag_get(I2C0, I2C_FLAG_RBNE)); *DataByte  = i2c_data_receive(I2C0);     i2c_ack_config(I2C0, I2C_ACK_ENABLE);     err = 0;return err;}uint8_t Write_Byte(uint16_t SlaveAddr,uint16_t WriteAddr,uint16_t WriteByte){uint8_t err = 0;    i2c_start_on_bus(I2C0);while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND));    i2c_master_addressing(I2C0, SlaveAddr<<1, I2C_TRANSMITTER);while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND));    i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);     while(!i2c_flag_get(I2C0, I2C_FLAG_TBE)); i2c_data_transmit(I2C0, WriteAddr);  while(!i2c_flag_get(I2C0, I2C_FLAG_TBE)); i2c_data_transmit(I2C0, WriteByte);  while(!i2c_flag_get(I2C0, I2C_FLAG_TBE)); i2c_stop_on_bus(I2C0);return err;}陀螺仪初始化:void mpu6050_init(){Write_Byte( SlaveAddress, PWR_MGMT_1,  0x00 );delay_1ms(10);Write_Byte( SlaveAddress, SMPLRT_DIV,  0x07 );delay_1ms(10);Write_Byte( SlaveAddress, CONFIG, 0x06 );delay_1ms(10);Write_Byte( SlaveAddress, GYRO_CONFIG,  0x18);delay_1ms(10);Write_Byte( SlaveAddress, ACCEL_CONFIG,  0x01);delay_1ms(10);}void GetData(uint16_t SlaveAddr,uint16_t REG_Address,short data[3]){uint8_t H=0,L=0;for(int i=0;i<3;i++){    Read_Byte(SlaveAddress, REG_Address+(i*2), &H);    Read_Byte( SlaveAddress, REG_Address+(i*2+1),&L);    data[i]=(( short)(H<<8))|L;}

(2)LCD驱动

驱动:

void LCD_GPIO_Init(void){     rcu_periph_clock_enable(RCU_GPIOA);     gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5);     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5);     gpio_bit_set(GPIOA,GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5);}void LCD_Writ_Bus(uint8_t dat){uint8_t i;LCD_CS_Clr();for(i=0;i<8;i++){    LCD_SCLK_Clr();    if(dat&0x80)    {LCD_MOSI_Set();    }    else    {LCD_MOSI_Clr();    }    LCD_SCLK_Set();    dat<>8);LCD_Writ_Bus(dat);}void LCD_WR_REG(uint8_t dat){LCD_DC_Clr();//д????LCD_Writ_Bus(dat);LCD_DC_Set();//д????}void LCD_Address_Set(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2){if(USE_HORIZONTAL==0){    LCD_WR_REG(0x2a);//?е??????    LCD_WR_DATA(x1+2);    LCD_WR_DATA(x2+2);    LCD_WR_REG(0x2b);//?е??????    LCD_WR_DATA(y1+1);    LCD_WR_DATA(y2+1);    LCD_WR_REG(0x2c);//??????д}else if(USE_HORIZONTAL==1){    LCD_WR_REG(0x2a);//?е??????    LCD_WR_DATA(x1+2);    LCD_WR_DATA(x2+2);    LCD_WR_REG(0x2b);//?е??????    LCD_WR_DATA(y1+1);    LCD_WR_DATA(y2+1);    LCD_WR_REG(0x2c);//??????д}else if(USE_HORIZONTAL==2){    LCD_WR_REG(0x2a);//?е??????    LCD_WR_DATA(x1+1);    LCD_WR_DATA(x2+1);    LCD_WR_REG(0x2b);//?е??????    LCD_WR_DATA(y1+2);    LCD_WR_DATA(y2+2);    LCD_WR_REG(0x2c);//??????д}else{    LCD_WR_REG(0x2a);//?е??????    LCD_WR_DATA(x1+1);    LCD_WR_DATA(x2+1);    LCD_WR_REG(0x2b);//?е??????    LCD_WR_DATA(y1+2);    LCD_WR_DATA(y2+2);    LCD_WR_REG(0x2c);//??????д}}void LCD_Init(void){LCD_GPIO_Init();LCD_RES_Clr();delay_1ms(100);LCD_RES_Set();delay_1ms(100);LCD_BLK_Set();    delay_1ms(100);delay_1ms(120);      LCD_WR_REG(0xB1); LCD_WR_DATA8(0x05); LCD_WR_DATA8(0x3C); LCD_WR_DATA8(0x3C); LCD_WR_REG(0xB2); LCD_WR_DATA8(0x05);LCD_WR_DATA8(0x3C); LCD_WR_DATA8(0x3C); LCD_WR_REG(0xB3); LCD_WR_DATA8(0x05); LCD_WR_DATA8(0x3C); LCD_WR_DATA8(0x3C); LCD_WR_DATA8(0x05); LCD_WR_DATA8(0x3C); LCD_WR_DATA8(0x3C); LCD_WR_REG(0xB4); //Dot inversion LCD_WR_DATA8(0x03); LCD_WR_REG(0xC0); LCD_WR_DATA8(0x28); LCD_WR_DATA8(0x08); LCD_WR_DATA8(0x04); LCD_WR_REG(0xC1); LCD_WR_DATA8(0XC0); LCD_WR_REG(0xC2); LCD_WR_DATA8(0x0D); LCD_WR_DATA8(0x00); LCD_WR_REG(0xC3); LCD_WR_DATA8(0x8D); LCD_WR_DATA8(0x2A); LCD_WR_REG(0xC4); LCD_WR_DATA8(0x8D); LCD_WR_DATA8(0xEE); LCD_WR_REG(0xC5); //VCOM LCD_WR_DATA8(0x1A); LCD_WR_REG(0x36); //MX, MY, RGB mode if(USE_HORIZONTAL==0)LCD_WR_DATA8(0x00);else if(USE_HORIZONTAL==1)LCD_WR_DATA8(0xC0);else if(USE_HORIZONTAL==2)LCD_WR_DATA8(0x70);else LCD_WR_DATA8(0xA0); LCD_WR_REG(0xE0); LCD_WR_DATA8(0x04); LCD_WR_DATA8(0x22); LCD_WR_DATA8(0x07); LCD_WR_DATA8(0x0A); LCD_WR_DATA8(0x2E); LCD_WR_DATA8(0x30); LCD_WR_DATA8(0x25); LCD_WR_DATA8(0x2A); LCD_WR_DATA8(0x28); LCD_WR_DATA8(0x26); LCD_WR_DATA8(0x2E); LCD_WR_DATA8(0x3A); LCD_WR_DATA8(0x00); LCD_WR_DATA8(0x01); LCD_WR_DATA8(0x03); LCD_WR_DATA8(0x13); LCD_WR_REG(0xE1); LCD_WR_DATA8(0x04); LCD_WR_DATA8(0x16); LCD_WR_DATA8(0x06); LCD_WR_DATA8(0x0D); LCD_WR_DATA8(0x2D); LCD_WR_DATA8(0x26); LCD_WR_DATA8(0x23); LCD_WR_DATA8(0x27); LCD_WR_DATA8(0x27); LCD_WR_DATA8(0x25); LCD_WR_DATA8(0x2D); LCD_WR_DATA8(0x3B); LCD_WR_DATA8(0x00); LCD_WR_DATA8(0x01); LCD_WR_DATA8(0x04); LCD_WR_DATA8(0x13); //------------------------------------End ST7735S Gamma Sequence-----------------------------// LCD_WR_REG(0x3A); //65k mode LCD_WR_DATA8(0x05); LCD_WR_REG(0x29); //Display on }显示函数:void LCD_Fill(uint16_t xsta,uint16_t ysta,uint16_t xend,uint16_t yend,uint16_t color){uint16_t i,j; LCD_Address_Set(xsta,ysta,xend-1,yend-1);//?????????Χfor(i=ysta;i<yend;i++){     for(j=xsta;j0)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;tdistance)    { xerr-=distance; uRow+=incx;    }    if(yerr>distance)    { yerr-=distance; uCol+=incy;    }}}void LCD_DrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2,uint16_t color){LCD_DrawLine(x1,y1,x2,y1,color);LCD_DrawLine(x1,y1,x1,y2,color);LCD_DrawLine(x1,y2,x2,y2,color);LCD_DrawLine(x2,y1,x2,y2,color);}void Draw_Circle(uint16_t x0,uint16_t y0,uint8_t r,uint16_t color){int a,b;a=0;b=r;      while(a(r*r))    { b--;    }}}void LCD_ShowChar(uint16_t x,uint16_t y,uint8_t num,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode){uint8_t temp,sizex,t,m=0;uint16_t i,TypefaceNum;uint16_t x0=x;sizex=sizey/2;TypefaceNum=(sizex/8+((sizex%8)?1:0))*sizey;num=num-' ';   LCD_Address_Set(x,y,x+sizex-1,y+sizey-1); for(i=0;i<TypefaceNum;i++){     if(sizey==12)temp=ascii_1206[num][i];     else if(sizey==16)temp=ascii_1608[num][i];      else if(sizey==24)temp=ascii_2412[num][i];      else if(sizey==32)temp=ascii_3216[num][i];      else return;    for(t=0;t<8;t++)    { if(!mode)//??????? {     if(temp&(0x01<<t))LCD_WR_DATA(fc);     else LCD_WR_DATA(bc);     m++;     if(m%sizex==0)     {  m=0;  break;     } } else {     if(temp&(0x01<<t))LCD_DrawPoint(x,y,fc);     x++;     if((x-x0)==sizex)     {  x=x0;  y++;  break;     } }    }}}void LCD_ShowString(uint16_t x,uint16_t y,const uint8_t *p,uint16_t fc,uint16_t bc,uint8_t sizey,uint8_t mode){while(*p!='\0'){    LCD_ShowChar(x,y,*p,fc,bc,sizey,mode);    x+=sizey/2;    p++;}  }uint32_t mypow(uint8_t m,uint8_t n){uint32_t result=1;     while(n--)result*=m;return result;}void LCD_ShowIntNum(uint16_t x,uint16_t y,uint16_t num,uint8_t len,uint16_t fc,uint16_t bc,uint8_t sizey){uint8_t t,temp;uint8_t enshow=0;uint8_t sizex=sizey/2;for(t=0;t<len;t++){    temp=(num/mypow(10,len-t-1))%10;    if(enshow==0&&t<(len-1))    { if(temp==0) {     LCD_ShowChar(x+t*sizex,y,' ',fc,bc,sizey,0);     continue; }else enshow=1; }     LCD_ShowChar(x+t*sizex,y,temp+48,fc,bc,sizey,0);}}void LCD_ShowFloatNum1(uint16_t x,uint16_t y,float num,uint8_t len,uint16_t fc,uint16_t bc,uint8_t sizey){uint8_t t,temp,sizex;uint16_t num1;sizex=sizey/2;num1=num*100;for(t=0;t<len;t++){    temp=(num1/mypow(10,len-t-1))%10;    if(t==(len-2))    { LCD_ShowChar(x+(len-2)*sizex,y,'.',fc,bc,sizey,0); t++; len+=1;    }     LCD_ShowChar(x+t*sizex,y,temp+48,fc,bc,sizey,0);}}

(3)主函数

void gd_led_config(void);void gd_led_toggle(void);int data[128]={0},data2[128]={0},data3[128]={0};short Acc[3],Gyro[3];void TIMER2_IRQHandler(void) {if(SET == timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_UP)){    /* clear channel 0 interrupt bit */    timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_UP);      GetData(SlaveAddress,ACCEL_XOUT_H,Acc);     GetData(SlaveAddress,GYRO_XOUT_H,Gyro);     gd_led_toggle();}}void nvic_config(void){nvic_irq_enable(TIMER2_IRQn, 0, 0);}void timer_config(void){TIMER2 Configuration:TIMER2CLK = SystemCoreClock/8400(GD32F330)or 10800(GD32F350) = 10KHz.the period is 1s(10000/10000 = 1s).timer_oc_parameter_struct timer_ocinitpara;timer_parameter_struct timer_initpara;/* enable the peripherals clock */rcu_periph_clock_enable(RCU_TIMER2);/* deinit a TIMER */timer_deinit(TIMER2);/* initialize TIMER init parameter struct */timer_struct_para_init(&timer_initpara);/* TIMER2 configuration */timer_initpara.prescaler  = 4999;timer_initpara.alignedmode= TIMER_COUNTER_EDGE;timer_initpara.counterdirection  = TIMER_COUNTER_UP;timer_initpara.period     = 999;timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;timer_init(TIMER2, &timer_initpara);/* clear channel 0 interrupt bit */timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_UP);/* enable the TIMER interrupt */timer_interrupt_enable(TIMER2, TIMER_INT_UP);/* enable a TIMER */timer_enable(TIMER2);}int main(void){gd_led_config();systick_config(); i2c0_gpio_config();i2c_config();mpu6050_init();LCD_Init();LCD_Fill(0,0,LCD_W,LCD_H,BLACK);//LCD_ShowString(0,0,"Hellow GD32F310G8!",WHITE,BLUE,12,0);  timer_config();/* configure the TIMER2 interrupt */nvic_config();while(1) { for(int i=0;i<128;i++){    LCD_DrawPoint( i, data[i],RED);    LCD_DrawPoint( i, data2[i],GREEN);    LCD_DrawPoint( i, data3[i],BLUE);      }   delay_1ms(10);  for(int i=0;i<128;i++){   LCD_DrawPoint( i, data[i],BLACK);   LCD_DrawPoint( i, data2[i],BLACK);   LCD_DrawPoint( i, data3[i],BLACK);   }   for(int i=0;i<127;i++){   data[i]=data[i+1];   data2[i]=data2[i+1];  data3[i]=data3[i+1]; } data[127]=20+(int)(((float)Gyro[0])/164); data2[127]=60+(int)(((float)Gyro[1])/164); data3[127]=100+(int)(((float)Gyro[2])/164);  //char cpd[10];   //sprintf(cpd,"%d",Acc[0]);      //LCD_ShowString(0,0,cpd,WHITE,BLUE,12,0); }}void gd_led_config(void){rcu_periph_clock_enable(RCU_GPIOA);gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_1);gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);GPIO_BC(GPIOA) = GPIO_PIN_1;}void gd_led_toggle(void){GPIO_TG(GPIOA) = GPIO_PIN_1;}

3.效果

【GD32F310开发板试用】GD32F310定时器采样MP6050并在彩色LCD上显示波形

GD32存在一个问题,用队列缓冲陀螺仪数据时,运行数秒后死机。