#include <stm32f10x.h>
#define _BV(n) (1 << (n))
uint32_t data;
uint8_t seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xa7, 0xa1, 0x86, 0x8e};
void delay(void)
{
uint32_t i;
for (i = 0; i < 2000; i++);
}
// 74HC595驅動數碼管
void SerIn(uint8_t data)
{
uint8_t i;
for (i = 0; i < 8; i++)
{
GPIOC->BRR = _BV(15); // 數據輸入時鐘線SHCP(=SCLK)->PC15, 上升沿有效
if (data & 0x80)
GPIOA->BSRR = _BV(0); // 串行數據輸入DS(=DIN)->PA0
else
GPIOA->BRR = _BV(0);
GPIOC->BSRR = _BV(15);
data <<= 1; // 先高位後低位
}
}
void ParOut(void)
{
GPIOC->BRR = _BV(14); // 輸出存儲器鎖存時鐘線STCP(=RCLK)->PC14, 上升沿
GPIOC->BSRR = _BV(14);
}
// 用8個數碼管顯示data變量的值
void seg_scan(uint8_t n)
{
uint8_t i;
uint32_t d = data;
while (n--)
{
for (i = 0; i < 8; i++)
{
SerIn(seg8[d & 0x0f]);
SerIn(_BV(i));
ParOut();
delay();
d >>= 4;
}
}
}
int main(void)
{
RCC->AHBENR = _BV(6); // 開啟CRC時鐘
RCC->APB2ENR = _BV(2) | _BV(4); // 開啟PA、PC時鐘
GPIOA->CRL = 0x00000003; // PA0設為輸出
GPIOC->CRH = 0x33300000; // PA13~15設為輸出
GPIOC->BSRR = _BV(13); // 熄滅LED指示燈
CRC->DR = 0xabcdef23;
data = CRC->DR; // 輸出0x4b1abbf3
//CRC->CR |= _BV(0); // 復位
CRC->DR = 0xabcdef23;
CRC->DR = 0x1138bb64;
data = CRC->DR; // 輸出0x6009af50
// 若不復位, 則輸出0x5b68f380
while (1)
{
seg_scan(1);
}
}