OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6333|回复: 4

STM32f103zet6用adc采集正弦波显示波形并求出频率

[复制链接]

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
130
金钱
130
注册时间
2021-5-5
在线时间
34 小时
发表于 2021-5-23 11:52:42 | 显示全部楼层 |阅读模式
#define N 80//采样次数
float Average(int a[])//求平均值
{
                int max,min,j;
                float average;
    max=min=a[0];//把数组第一个数赋值给max和min
    for(j=1;j<N;j++)//依次判断剩下每个数
                {
        if(a[j]>max) max=a[j];//如果该数大于max,把其赋值给max
        if(a[j]<min) min=a[j];//如果该数小于min,把其赋值给min
    }
    average=(max+min)/2;
                return average;
}
void OLED_Fixed()//显示屏幕上固定的东西
{
       
       
                 OLED_ShowChinese(0,0,0,16,1); //频
        OLED_ShowChinese(16,0,1,16,1); //率
         OLED_ShowString(0,16,"      Hz",12);
        OLED_ShowChinese(0,32,2,16,1); //峰
        OLED_ShowChinese(16,32,2,16,1); //峰
         OLED_ShowChinese(32,32,3,16,1); //值
          OLED_ShowString(0,48," .    V",12);
        OLED_Refresh_Gram();                //更新显示到OLED  
         OLED_Fill(48,0,48,63,1);//显示y轴
                OLED_Fill(48,63,127,63,1);//显示x轴
}
float MAX_MIN(int a[])//求峰峰值
        {
                int max,min,j;
                float sub;
    max=min=a[0];//把数组第一个数赋值给max和min
    for(j=1;j<N;j++)//依次判断剩下每个数
                {
        if(a[j]>max) max=a[j];//如果该数大于max,把其赋值给max
        if(a[j]<min) min=a[j];//如果该数小于min,把其赋值给min
    }
    sub=(max-min)*(3.3/4095);//测得的电压(3.3/4095)为分辨率
                return sub;
        };
       
       
        float TIME(int a[])//求波形的周期
        {
                float aver=Average(a);
                        int s,g,k=0,m,n,z,b,c,l;
                                for(s=0;s<N;s++)
                {
                if(a[s]<=aver)
                        a[s]=0;
                else
                        a[s]=1;
        }        //变换成方波
               
                for(g=1;g<N;g++)
        {
                if(a[g]==a[k]);
                else
                {
                        k=g;
                        break;
                }
        }
        for(m=k+1,n=k;m<N;m++)
        {
                if(a[m]==a[n]);
                else
                {
                        b=m;
                        z=m-n;
                        break;
                }
        }
                for(c=b+1,l=b;c<N;c++)
        {
                if(a[l]==a[c]);
                else
                {
                        z=z+c-l;
                        break;
                }
        }
        return 2*z;
        };
       
       
int main(void)
{       
        int i;
        int volt[N];//记录采样到的电压
        u8 xpoint=48;
  u16 adcx;
        u8 ypoint;
        float temp;
         
         
         
        delay_init();  //没有这个就什么都不显示
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);         //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
        LED_Init();
        OLED_Init();                        //初始化OLED                      
        Adc_Init();                                  //ADC初始化
        uart_init(115200);                 //串口初始化为115200
  OLED_Clear();
        OLED_Fixed();
               
        while(1)
        {       
                for(i=0;i<N;i++)
                {
                volt[i]=Get_Adc_Average(ADC_Channel_1,15);
                ypoint=volt[i]*63/4096;//得到y值
                OLED_DrawPoint(xpoint,ypoint,1);//画出y值
                                        OLED_Refresh_Gram();       
                if(xpoint<127)
                        xpoint++;
                else
                {
                        xpoint=48;
                        OLED_Fill(49,0,127,62,0);
                }
          }//画图像
                Average(volt);
    temp=MAX_MIN(volt);

                adcx=temp;//电压的整数部分
                OLED_ShowNum(0,48,adcx,1,12);//显示峰峰值
                temp-=adcx;//电压的小数部分
                temp*=1000;
                OLED_ShowNum(16,48,temp,3,12);
                if(temp<10)
                OLED_ShowString(16,48,"00",12);       
                if(temp<100||temp>=10)
                OLED_ShowString(16,48,"0",12);       
                OLED_ShowNum(0,16,12000000/(TIME(volt)*241),5,12);//显示频率
                }
}
求助,为啥显示的图形只有一点变化
实际频率为500HZ,峰峰值为2V
但是在频率为1kHZ的时候图形稍微好点

IMG_20210523_115002.jpg
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

24

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
265
金钱
265
注册时间
2020-11-19
在线时间
33 小时
发表于 2021-9-7 16:19:56 | 显示全部楼层
楼主 你这个频率是怎么采集的 程序能不能开源一下
回复 支持 1 反对 0

使用道具 举报

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
130
金钱
130
注册时间
2021-5-5
在线时间
34 小时
 楼主| 发表于 2021-5-23 11:53:50 | 显示全部楼层
有更好的方法吗?
回复 支持 1 反对 0

使用道具 举报

12

主题

3394

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8663
金钱
8663
注册时间
2020-5-11
在线时间
4129 小时
发表于 2021-5-24 16:27:08 | 显示全部楼层
看样子,Get_Adc_Average有问题。
专治疑难杂症
回复 支持 反对

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
24
金钱
24
注册时间
2021-4-24
在线时间
7 小时
发表于 2021-5-25 16:18:09 | 显示全部楼层
我也想求助,波形显示怎么做
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-6 20:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表