完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
由于3个文件,我一个一个贴上来,若运行有问题,自己修改下 头文件即可 硬件 PC1 作为信号输入口 串口使用UART2 PD5 PD6 主文件 /* MAIN.C file * * 实现功能 通过tiM1 输入捕获功能测量信号的周期和占空比 这个与上一个例子相似,但增加了 * 占空比的测量 。 * 步骤: * 1、选择TIM1_CCR1 的有效输入配置输入捕获 功能 * 2,选择TI1FP1 的有效极性 用来捕获数据到TIM1_CCR1 和清除计数器 * 选择上升还是下降沿有效 * 3、选择TIM1_CCR1 的有效输入 TIM1_CCMR2 寄存器 CC2S 选中 TI2FP2 * 4,选择有效的惩罚信号 * 5,选择TI1FP2 的捕获极性 *6 , 配置触发模式控制器为复位惩罚模式 * 7,使能捕获功能 * 整体思路:当捕获到第一个上升沿定时器开始定时计数;捕获到 * 下降沿时将定时器中的数据保存下来,当捕获到第二个上升沿时 * 将当前定时器值在保存下来,并清0 定时器重新计数 * 达到的 第一个就是 信号 就是信号宽度 * 达到 的第二个信号 就是 信号周期 * 第一个值 / 第二个值 就是占空比 * 这里用到复位触发模式 是指 当一个触发输入事件发生时 * 计数器和它的预分频器能够重新被初始化 * 通过串口输出 * 测的外部 100Khz * 这里需要关闭CC0 时钟否则 测的频率不稳定 * 串口用外部时钟 16Mhz 9600波特率 * 亲测 测的频率 101Khz 占空比 49.4% * 采用外部输入一个100KHZ 的信号 占空比 50% 存在误差 */ #include "common.h" //头文件 可以去掉的 unsigned long f; unsigned char dutycycle; unsigned int value1,value2; unsigned char gewei,shiwei,baiwei,qianwei,dutycycle1,dutycycle2; //配置系统时钟 void CLK_Init(void) { //CLK_CKDIVR = 0x11; // 10: fHSI = fHSI RC output/ 4 // = 16MHZ / 4 =4MHZ // 001: fCPU=fMASTER/2. = 2MHZ CLK_ECKR |=0X1; //开启外部时钟 while(!(CLK_ECKR&0X2)); //等待外部时钟rdy //外部晶振 = 8MHz //CLK_CKDIV = 0XF8 1111 1000 //CLK_CKDIVR &= 0X00; //CPU无分频 //CLK_CKDIVR &= 0X07; //*** = 125khz //CLK_CKDIVR = 0X00; //不分频 // 16000000 /8 = 2MHZ CLK_CKDIVR = 0X00; // 16分频 //16000.000/16 = 1MHZ CLK_SWR = 0XB4; //选择外部时钟 while(!(CLK_SWCR&0X8)); //这里要等 CLK_SWCR |=0X02; //使能外部时钟 } void delay_ms(u8 ms) { u8 i,j; while(ms--) { for(i=4;i!=0;i--) for(j=100;j!=0;j--); } } void main() { _asm("sim"); UART2_Init();// 串口初始化 CLK_Init(); //时钟初始化 //CLK_CKDIVR = 0X00; tim1_init(); //定时器初始化 //cco_init(); _asm("rim"); while (1) { TIM1_SR1 &=0xf9;//0B11111001; //CC2IF CC2 通道配置为输入模式 当捕获事件发生时 该位由硬件置1 软件清0 //CC1IF CC1 首先把状态位 置 0 TIM1_SR2 &=0xfd;//0B11111101; //CC1OF 捕获比较重复捕获标记 //=0 无重复捕获产生 //先把 重复捕获标志位 清 0 TIM1_CCER1 |=0X11; //CC1 通道配置为输入 =1 捕获使能 //CC2 通道配置为输入 =1 捕获使能 while(!(TIM1_SR1 & 0X02)); //等待通道CC1IF 计数器捕获 while(!(TIM1_SR1 & 0X04)); //等待通道CC2IF 计数器捕获 value1 =(unsigned int) TIM1_CCR2H<<8; value1 |= TIM1_CCR2L; //存储捕获比较寄存器 2 数值 while(!(TIM1_SR1 & 0X02)); //在此 等待通道CC1IF计数器捕获数值 value2 =(unsigned int)TIM1_CCR1H<<8; value2 |= TIM1_CCR1L; //TIM1_CCER1 &=0B11101110; //禁止捕获比较1 =0 //禁止捕获比较2 =0 //关闭捕获功能 f =(16000000UL/value2); //测试信号的频率 //f = f/100; //KHZ 小数点显示 别忘了上一个程序 //f=101 dutycycle = value1/value2; //占空比出来 //为什么*100 25% 30% 占空比否则小数很小明白不 //一般我们说占空比 都是 20% 30% 这里 *100 直接显示的是 20 30 //明白了 //for(i=0;i<400;i++) //延时作用 注释掉也行 // display(); //数码管显示 printf("value1:%drn",value1); printf("value2:%drn",value2); //printf("频率:%drn",f); //printf("占空比:%drn",dutycycle); } } /*************************************/ 由于串口使用了中断 下面是中断函数 /* BASIC INTERRUPT VECTOR TABLE FOR STM8 devices * Copyright (c) 2007 STMicroelectronics */ #include "common.h" typedef void @far (*interrupt_handler_t)(void); struct interrupt_vector { unsigned char interrupt_instruction; interrupt_handler_t interrupt_handler; }; @far @Interrupt void NonHandledInterrupt (void) { /* in order to detect unexpected events during development, it is recommended to set a breakpoint on the following instruction */ return; } @far @interrupt void NonHandledInterrupt_UART2RX (void) { /* in order to detect unexpected events during development, it is recommended to set a breakpoint on the following instruction */ UART2_SR &= 0xdf; UART2_Send(UART2_DR); return; } extern void _stext(); /* startup routine */ struct interrupt_vector const _vectab[] = { {0x82, (interrupt_handler_t)_stext}, /* reset */ {0x82, NonHandledInterrupt}, /* trap */ {0x82, NonHandledInterrupt}, /* irq0 */ {0x82, NonHandledInterrupt}, /* irq1 */ {0x82, NonHandledInterrupt}, /* irq2 */ {0x82, NonHandledInterrupt}, /* irq3 */ {0x82, NonHandledInterrupt}, /* irq4 */ {0x82, NonHandledInterrupt}, /* irq5 */ {0x82, NonHandledInterrupt}, /* irq6 */ {0x82, NonHandledInterrupt}, /* irq7 */ {0x82, NonHandledInterrupt}, /* irq8 */ {0x82, NonHandledInterrupt}, /* irq9 */ {0x82, NonHandledInterrupt}, /* irq10 */ {0x82, NonHandledInterrupt}, /* irq11 */ {0x82, NonHandledInterrupt}, /* irq12 */ {0x82, NonHandledInterrupt}, /* irq13 */ {0x82, NonHandledInterrupt}, /* irq14 */ {0x82, NonHandledInterrupt}, /* irq15 */ {0x82, NonHandledInterrupt}, /* irq16 */ {0x82, NonHandledInterrupt}, /* irq17 */ {0x82, NonHandledInterrupt}, /* irq18 */ {0x82, NonHandledInterrupt}, /* irq19 */ {0x82, NonHandledInterrupt}, /* irq20 */ {0x82, NonHandledInterrupt_UART2RX}, /* irq21 */ {0x82, NonHandledInterrupt}, /* irq22 */ {0x82, NonHandledInterrupt}, /* irq23 */ {0x82, NonHandledInterrupt}, /* irq24 */ {0x82, NonHandledInterrupt}, /* irq25 */ {0x82, NonHandledInterrupt}, /* irq26 */ {0x82, NonHandledInterrupt}, /* irq27 */ {0x82, NonHandledInterrupt}, /* irq28 */ {0x82, NonHandledInterrupt}, /* irq29 */ }; /*************************************************/ 串口函数如下 ,记得修改 串口波特率 因为用2MHZ 与 16MHZ /*************** (C) COPYRIGHT EW工作室 *************************************** * 文件名 :uart.c * 描述 :串口调试文件 * 实验平台:EW STM8开发板 V1 * 库版本 :V2.1.0 * 作者 :EW QQ:307298507 * 公众微信:eworld2013 * 修改时间:2013-07-20 *******************************************************************************/ /* 包含系统头文件 */ /* 包含自定义头文件 */ #include "uart.h" /* 自定义新类型 */ /* 自定义宏 */ /* 自定义变量 */ /*实现函数部分*/ /******************************************************************************* * 名称: Uart_Init * 功能: UART2初始化操作 * 形参: 无 * 返回: 无 * 说明: 无 ******************************************************************************/ /* void UART2_Init(void) { UART2_CR1=0x00; UART2_CR2=0x00; UART2_CR3=0x00; UART2_BRR2 = 0x07; UART2_BRR1 = 0x01; //115200波特率 UART2_CR2 = 0x2c; //允许发送 允许接收 接收中断使能 } */ void UART2_Init(void) { UART2_CR1 = 0X00; //控制寄存器 1 //R8存放接收到的字第9位 //T8 存放发送字的第9位 //UARTD=0 使能 //WAIE 被空闲总线唤醒 //PCEN UART 模式=0 奇偶校验 禁止 //PS 奇偶校验选择 这里不选择 //PIEN 校验中断 = 0 禁止 UART2_CR2 = 0X0C;//0000 1100 //发送接收使能 UART2_CR3 = 0X00; //0010 //00 1个停止位 //01 保留 //10 2个停止位 // 11 1.5 个停止位 //UART2_BRR2 = 0X00; //2MHZ 下9600 //UART2_BRR1 = 0X0D; //2000000/9600 = 208 =D0 =00D0 UART2_BRR2 = 0X03; //16MHZ 下9600 UART2_BRR1 = 0X68; //设置波特率 //这个波特率设置很有意思 //不是直接赋值 而是 达到的 16进制数 // 中间两位赋值 给BRR1 两边2为赋值给BRR2 //2000000/2400=833=0341 //16000000/2400 = 6666 =1a0a =2400b波特率 //16000/9600=683 } void UART2_Send(u8 dat) { while((UART2_SR & 0x80)==0x00); UART2_DR = dat; } /******************************************************************************* * 名称: UART2_SendString * 功能: UART2发送len个字符 * 形参: data -> 指向要发送的字符串 * len -> 要发送的字节数 * 返回: 无 * 说明: 无 ******************************************************************************/ void UART2_SendString(u8* Data) { u16 i=0; //for(; i < len; i++) while(Data!=' |