找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5320|回复: 3
打印 上一主题 下一主题
收起左侧

stm8s单片机简易1kHz至1MHz方波信号频率计源码

[复制链接]
跳转到指定楼层
楼主
ID:312538 发表于 2018-6-7 09:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
小王子实战@简易1kHz至1MHz方波信号频率计

/***********************************************************
* 实验名称及内容:简易1kHz至1MHz方波信号频率计
* 配套书籍:《深入浅出STM8单片机入门、进阶与应用实例》
* 实验平台及编程人员:思修电子工作室"祥云小王子"开发版 Long
***************************************************************/
#include "iostm8s208mb.h"//主控芯片的头文件
/************************常用数据类型定义**********************/
#define u8  uint8_t
#define u16 uint16_t
#define u32 uint32_t
typedef unsigned char    uint8_t;
typedef unsigned short   uint16_t;
typedef unsigned long    uint32_t;
/***********************端口/引脚定义区域**********************/
#define  LCDRS          PF_ODR_ODR0     //LCD1602数据/命令选择端口
#define  LCDRW          PF_ODR_ODR3     //LCD1602读写控制端口
#define  LCDEN          PF_ODR_ODR4     //LCD1602使能信号端口
#define  LCDDATA        PB_ODR          //LCD1602数据端口D0至D7
/**********************用户自定义数据区域**********************/
u8 table1[]="=Frequency Test=";//LCD1602显示字符串数组1显示界面
u8 table2[]="f:            Hz";//LCD1602显示字符串数组2显示界面
u8 table3[]={'0','1','2','3','4','5','6','7','8','9'};//数字字符
static u16 A_num,B_num,SYS_num;//定义A_num、B_num变量用于装载两次边沿时间
//SYS_num用于存放周期计数值
static unsigned long F_num;//用于存放频率值
#define SYS_CLOCK 8034400UL//定义系统当前fmaster频率值
/************************函数声明区域*************************/
void delay(u16 Count);//延时函数声明
void GPIO_init(void);//GPIO端口初始化配置函数声明
void TIM1_init(void);//TIM1初始化函数声明
void LCD1602_init(void);//LCD1602初始化函数
void LCD1602_DIS_CHAR(u8 x,u8 y,u8 z);//在设定地址写入字符数据
void LCD1602_Write(u8 cmdordata,u8 writetype);//写入液晶模组命令或数据
void LCD1602_DIS(void);//显示字符函数
/**************************主函数区域*************************/
int main(void)
{
  u8 i,baiwan,shiwan,wan,qian,bai,shi,ge;//i为循环控制,其它为取位变量
  CLK_CKDIVR=0x08;//设置系统时钟为HSI内部8MHz时钟
  delay(10);//延时等待稳定
  GPIO_init();//初始化相关GPIO引脚配置
  LCD1602_init();//LCD1602初始化
  LCD1602_DIS();//显示字符
  TIM1_init();//TIM1相关功能配置初始化
  TIM1_CCER1&=0xFE;//捕获功能禁止
  LCD1602_Write(0xC0,0);//选择第二行
  for(i=0;i<16;i++)
  {
      LCD1602_Write(table2[ i],1);//写入table2[]内容
      delay(5);
  }
  while(1)
  {
    TIM1_CCR1H=0x00;//清除捕获/比较寄存器1高8位
    TIM1_CCR1L=0x00;//清除捕获/比较寄存器1低8位
    TIM1_CCER1|=0x01;//捕获功能使能
    while((TIM1_SR1&0x02)==0);//等待捕获比较1标志位CC1IF变为“1”
    A_num=(u16)TIM1_CCR1H<<8;//取回捕获/比较寄存器1高8位
    A_num|=TIM1_CCR1L;//取回捕获/比较寄存器1低8位并与高8位拼合
    while((TIM1_SR1&0x02)==0);//等待捕获比较1标志位CC1IF变为“1”
    B_num=(u16)TIM1_CCR1H<<8;//取回捕获/比较寄存器1高8位
    B_num|=TIM1_CCR1L;//取回捕获/比较寄存器1低8位并与高8位拼合
    TIM1_CCER1&=0xFE;//捕获功能禁止
    SYS_num=B_num-A_num;//得到信号周期计数值
    F_num=(8*SYS_CLOCK)/SYS_num;//计算频率值
    baiwan=F_num/1000000;//取出百万位
    shiwan=F_num%1000000/100000;//取出十万位
    wan=F_num%100000/10000;//取出万位
    qian=F_num%10000/1000;//取出千位
    bai=F_num%1000/100;//取出百位
    shi=F_num%100/10;//取出十位
    ge=F_num%10;//取出个位
    LCD1602_DIS_CHAR(2,4,table3[baiwan]);//百万位显示到2行第4字符位
    LCD1602_DIS_CHAR(2,5,'.');//显示分隔小数点
    LCD1602_DIS_CHAR(2,6,table3[shiwan]);//十万位显示到2行第6字符位
    LCD1602_DIS_CHAR(2,7,table3[wan]);//万位显示到2行第7字符位
    LCD1602_DIS_CHAR(2,8,table3[qian]);//千位显示到2行第8字符位
    LCD1602_DIS_CHAR(2,9,'.');//显示分隔小数点
    LCD1602_DIS_CHAR(2,10,table3[bai]);//百位显示到2行第10字符位
    LCD1602_DIS_CHAR(2,11,table3[shi]);//十位显示到2行第11字符位
    LCD1602_DIS_CHAR(2,12,table3[ge]);//个位显示到2行第12字符位
  }
}
/****************************************************************/
//延时函数delay(),有形参Count用于控制延时函数执行次数,无返回值
/****************************************************************/
void delay(u16 Count)
{
  u8 i,j;
  while (Count--)//Count形参控制延时次数
  {
    for(i=0;i<50;i++)
      for(j=0;j<20;j++);
  }
}
/****************************************************************/
//GPIO端口初始化配置函数GPIO_init(),无形参,无返回值
/****************************************************************/
void GPIO_init(void)
{
  //1.配置LCD1602数据口PB
  PB_DDR=0xFF; //配置PB端口为输出端口
  PB_CR1=0xFF; //配置PB端口为推挽输出模式
  PB_CR2=0x00; //配置PB端口为低速斜率输出
  LCDDATA=0xFF;//初始化PB端口全部输出高电平
  //2.配置LCD1602液晶RS引脚
  PF_DDR_DDR0=1;//配置PF0为输出模式
  PF_CR1_C10=1; //配置PF0为推挽输出模式
  PF_CR2_C20=0; //配置PF0低速率输出
  //3.配置LCD1602液晶RW引脚
  PF_DDR_DDR3=1;//配置PF3为输出模式
  PF_CR1_C13=1; //配置PF3为推挽输出模式
  PF_CR2_C23=0; //配置PF3低速率输出
  LCDRW=0;      //配置LCD1602为写入模式
  //4.配置LCD1602液晶EN引脚
  PF_DDR_DDR4=1;//配置PF4为输出模式
  PF_CR1_C14=1; //配置PF4为推挽输出模式
  PF_CR2_C24=0; //配置PF4低速率输出
}
/****************************************************************/
//TIM1功能初始化函数TIM1_init(),无形参,无返回值
/****************************************************************/
void TIM1_init(void)
{
  //1.CC1通道被配置为输入,IC1映射在TI1FP1上“CC1S[1:0]=01”
  TIM1_CCMR1|=0x01;
  //2.配置采样率为主时钟频率,无滤波器“IC1F[3:0]=0000”
  TIM1_CCMR1&=0x0F;
  //3.配置信号边沿极性为TI1F或TI2F的低电平或下降沿“CC1P=1”
  TIM1_CCER1|=0x02;
  //4.配置输入/捕获1通道预分频器因子为8分频“IC1PSC[1:0]=11”
  TIM1_CCMR1|=0x0C;
  //5.使能TIM1_CH1输入捕获功能“CC1E=1”
  TIM1_CCER1|=0x01;
  //6.使能TIM1计数器功能“CEN=1”
  TIM1_CR1|=0x01;
}
/****************************************************************/
//LCD1602初始化函数LCD1602_init(),无形参和返回值
/****************************************************************/
void LCD1602_init(void)
{
  LCD1602_Write(0x38,0);//配置16*2显示,5*7点阵,8位数据接口
  LCD1602_Write(0x0C,0);//设置开显示,不显示光标
  LCD1602_Write(0x06,0);//写字符后地址自动加1
  LCD1602_Write(0x01,0);//显示清0,数据指针清0
}
/****************************************************************/
//设定地址写入字符函数LCD1602_DIS_CHAR(),有形参x、y、z无返回值
//x表示1602液晶的行,y表示列地址,z表示欲写入的字符
/****************************************************************/
void LCD1602_DIS_CHAR(u8 x,u8 y,u8 z)
{
  u8 address;
  if(x==1)//若欲显示在第一行
    address=0x80+y;//第一行的行首地址+列地址
  else
    address=0xC0+y;//第二行的行首地址+列地址
  LCD1602_Write(address,0);//设定显示地址
  LCD1602_Write(z,1);//写入字符数据
}
/****************************************************************/
//写入液晶模组命令或数据函数LCD1602_Write(),有形参cmdordata和
//writetype,无返回值。
/****************************************************************/
void LCD1602_Write(u8 cmdordata,u8 writetype)
{
  if(writetype==0)//判断写入类型
    LCDRS=0;//写入命令信息
  else
    LCDRS=1;//写入数据信息
  LCDDATA=cmdordata;//向数据线端口写入信息
  delay(5);//延时等待稳定
  LCDEN=1;//模块使能
  delay(5);//延时等待写入
  LCDEN=0;//模块不使能
}
/****************************************************************/
//显示字符函数LCD1602_DIS(),无形参和返回值
/****************************************************************/
void LCD1602_DIS(void)
{
  u8 i;//定义控制循环变量i
  LCD1602_Write(0x80,0);//选择第一行
  for(i=0;i<16;i++)
  {
      LCD1602_Write(table1[ i],1);//写入table1[]内容
      delay(5);
  }
  LCD1602_Write(0xC0,0);//选择第二行
  for(i=0;i<16;i++)
  {
      LCD1602_Write('>',1);//带延时逐一显示字符“>”模拟进度条
      delay(50);
  }
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:992802 发表于 2021-12-15 16:49 | 只看该作者
楼主 如果要是利用STM8单片机制作一个频率计,测量0-1KHZ方波信号的频率,利用OLED显示频率,通过串口读取信号频率。应该怎么写程序啊 求指点了
回复

使用道具 举报

板凳
ID:992802 发表于 2021-12-15 16:51 | 只看该作者
楼主 麻烦问下要是利用STM8单片机制作一个频率计,测量0-1KHZ方波信号的频率,利用OLED显示频率,通过串口读取信号频率。应该怎么写程序啊 求楼主指点哈
回复

使用道具 举报

地板
ID:1104990 发表于 2023-12-18 19:52 | 只看该作者
JWChen 发表于 2021-12-15 16:49
楼主 如果要是利用STM8单片机制作一个频率计,测量0-1KHZ方波信号的频率,利用OLED显示频率,通过串口读取 ...

麻烦问一下,找到怎么做了吗,同问题求助
回复

使用道具 举报

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

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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