全国服务热线

18219276011

2850818308

您当前位置:首页>>升威资讯
升威资讯
公司新闻
企业视频
行业资讯
技术支持
广东升威电子制品有限公司
地址:东莞市塘厦镇凤凰岗凤清路39号升威工业园
电话:0769-38833333-881
销售电话:18219276011
传真:0769-87930111
E-mail:sw@soundwell-cn.com
编码开关应用在STM32单片机
发布时间:2019-03-08
发布者:
浏览次数:84次

小编在网上找到了一个编码开关的程序,原创作者 巨大八爪鱼,分享给大家,有需要的朋友们可以看一下.


/* 本程序测试时使用的是锐志电子六合一扩展板上的数字旋转编码开关 */
#include <stm32f10x.h>
 
int main(void)
{
    /* 打开外设时钟 */
    RCC->APB1ENR = RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM3EN;
    RCC->APB2ENR = RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN;
    
    /* I/O端口配置 */
    GPIOA->CRL = 0x88000000; // PA6为通道1, PA7为通道2, 设为带电阻输入
    GPIOA->BSRR = GPIO_BSRR_BS6 | GPIO_BSRR_BS7; // PA6~7带上拉电阻输入
    GPIOA->CRH = 0x00080000; // PA12设为带电阻输入
    GPIOA->BSRR = GPIO_BSRR_BS12;
    GPIOB->CRH = 0x33333333; // 数码管段选
    GPIOC->ODR = 0x3000; // 熄灭数码管
    GPIOC->CRH = 0x00333333; // 数码管位选
    
    /* 数码管扫描中断配置 */
    // 每隔一定时间点亮一个数码管
    // 从低位向高位扫描
    TIM2->ARR = 29; // 0~29有30个数字, 定时时间30*0.1ms=3ms, 向上计数, 每当TIM2->CNT跳变到0时触发一次中断
    TIM2->PSC = 7199; // 对72MHz进行7200分频, 得到的频率是10kHz, 也就是0.1ms
    TIM2->EGR = TIM_EGR_UG; // 立即触发TIM2中断, 点亮数码管, 同时刷新寄存器
    TIM2->DIER = TIM_DIER_UIE; // 允许触发定时器溢出中断
    NVIC_EnableIRQ(TIM2_IRQn); // 允许执行中断服务函数, 该函数位于core_cm3.h, 是MDK自带的函数, 不是库函数
    TIM2->CR1 = TIM_CR1_CEN; // 开定时器
    
    /* 数字编码开关计数器配置 */
    // 将数字编码开关的1、3脚分别接到TIM3定时器的通道1~2输入端口PA6~7上
    TIM3->ARR = TIM_ARR_ARR; // 计数的最大值为65535
    TIM3->CCMR1 = TIM_CCMR1_CC1S_0; // CC1S=01(IC1映射到TI1)
    TIM3->CCMR1 |= TIM_CCMR1_CC2S_0; // CC2S=01(IC2映射到TI2)
    
    // 以下三种模式任选一种即可
    TIM3->SMCR = TIM_SMCR_SMS_0; // SMS=001, 对通道1计数
    //TIM3->SMCR = TIM_SMCR_SMS_1; // SMS=010, 对通道2计数
    //TIM3->SMCR = TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0; // SMS=011, 同时对通道1,2计数(计数速度更快)
    
    TIM3->CCER = TIM_CCER_CC1P; // 反转TI1的电平, 顺时针旋转时使计数值增加而不是减少(默认是减少)
    // 也可以改为反转TI2的电平, 这个和上面SMS的选择无关
    
    TIM3->EGR = TIM_EGR_UG; // 刷新寄存器
    TIM3->CR1 = TIM_CR1_CEN; // 开始计数
    
    /* 开PA12外中断 */
    EXTI->IMR = EXTI_IMR_MR12;
    EXTI->FTSR = EXTI_FTSR_TR12; // 下降沿触发
    NVIC_EnableIRQ(EXTI15_10_IRQn);
    NVIC_SetPriority(EXTI15_10_IRQn, 1); // 该中断优先级比数码管扫描中断的优先级低, 不会影响数码管扫描
    
    while (1);
}
 
// 数码管动态扫描
void TIM2_IRQHandler(void)
{
    static uint8_t pos = 5;
    static uint32_t numbuf;
    const uint8_t seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};
    if (TIM2->SR & TIM_SR_UIF) // 定时器2溢出中断
    {
        TIM2->SR &= ~TIM_SR_UIF; // 清中断标志
        if (pos == 5)
            numbuf = TIM3->CNT; // 取定时器3的计数值
        else
            numbuf /= 10;
        
        GPIOC->ODR = (GPIOC->ODR & 0xf0ff) | 0x3000; // 关闭位选
        GPIOB->ODR = (GPIOB->ODR & 0xff) | (seg8[numbuf % 10] << 8); // 设置显示字符
        if (pos <= 3)
            GPIOC->ODR |= 1 << (pos + 8); // 数码管1~4的位选直连I/O端
        else
            GPIOC->ODR &= ~(1 << (pos + 8)); // 数码管5~6的位选是由PNP三极管驱动
        if (pos == 0)
            pos = 5;
        else
            pos--;
    }
}
 
// 编码开关按键按下中断
void EXTI15_10_IRQHandler(void)
{
    EXTI->PR |= EXTI_PR_PR12; // 清中断标志
    TIM3->EGR = TIM_EGR_UG; // 重置定时器3, 使计数值归0
}


广东升威电子专业生产旋转编码开关28年,编码开关型号齐全多选,质量安全可靠,找编码开关厂家首选老牌编码器厂家升威电子.




编码开关厂家


最新案例