【程序】
#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);
}
}
}