【程序】 #include <stm32f10x.h>
#define _BV(n) (1 << (n))
uint8_t i = 0; uint8_t seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};
void delay(void) { uint32_t i; for (i = 0; i < 20000; i++); }
void SerIn(uint8_t data) { uint8_t i; for (i = 0; i < 8; i++) { GPIOC->BRR = _BV(15); if (data & 0x80) GPIOA->BSRR = _BV(0); else GPIOA->BRR = _BV(0); GPIOC->BSRR = _BV(15); data <<= 1; } }
void ParOut(void) { GPIOC->BRR = _BV(14); GPIOC->BSRR = _BV(14); }
int main(void) { // OC1输出端PA8用杜邦线接PA15, OC1N互补输出端PB13接PC13 // 同时PC13上有一个低电平点亮的LED指示灯 RCC->APB2ENR = _BV(2) | _BV(3) | _BV(4) | _BV(11); // 开启PA、PB、PC和TIM1时钟, 不需要开启AFIO的时钟 GPIOA->CRH = 0x8000000b; // PA15设为带下拉的输入, PA8设为复用50MHz推挽输出 GPIOA->CRL = 0x00000003; // PA0设为50MHz推挽输出 GPIOB->CRH = 0x00b00000; // PB13设为复用50MHz推挽输出 GPIOC->CRH = 0x33800000; // PC13设为带下拉的输入, PC14~15设为50MHz推挽输出
TIM1->ARR = 5099; // 计数值 TIM1->PSC = 65535; // 定时器分频 TIM1->CCR1 = 2000; TIM1->CCMR1 = 0x70; // OC1M=111, PWM模式2, 输出比较匹配时OC1REF信号产生上升沿 TIM1->BDTR = 0x80ff; // MOE=1, 并添加死区时间, 大约为几us, 输出端OC1的dead-time延迟产生在OC1REF信号的上升沿 // TIM1->BDTR = 0x8000; // 不加死区时间的情况 TIM1->CCER = 0x05; // CC1NE=1, CC1E=1 // 刷新寄存器 TIM1->CR1 = 0x204; // CKD=10, URS=1 TIM1->EGR = 0x01; // UG=1 // 开始计数 TIM1->CR1 |= _BV(0); // CEN=1 SerIn(seg8[0]); SerIn(_BV(0)); ParOut(); while (1) { // 如果检测到OC1、OC1N同时输出低电平, 则表明有dead-time延迟 if ((GPIOA->IDR & _BV(15)) == 0 && (GPIOC->IDR & _BV(13)) == 0) { i++; if (i > 9) i = 0; SerIn(seg8[i]); SerIn(_BV(0)); ParOut(); while ((GPIOA->IDR & _BV(15)) == 0 && (GPIOC->IDR & _BV(13)) == 0); } } }
|