打印
[STM8]

发现一个宝贝

[复制链接]
604|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yiy|  楼主 | 2019-12-6 16:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

https://jaist.dl.sourceforge.net/project/sdcc/sdcc-win32/3.9.0/sdcc-3.9.0-setup.exe
我先试试怎么用,好用了,再来分享刚才一不小心发现的。

使用特权

评论回复
沙发
yiy|  楼主 | 2019-12-6 17:14 | 只看该作者
/*
*/

#include <mcs51/8051.h>
void delay(int);

void main(void)
{
int i;
P2=0x01;
delay(500);
while(1)
{
  for(i=0;i<7;i++)
  {
     P2<<=1;
     delay(500);
  }
   P2=0x01;
delay(500);
}
}
void delay(int x)
{
   int i,j;
   for(i=x;i>0l;i--)
     for(j=110;j>0;j--);
}


先写了个51的跑马灯,非常的OK。

使用特权

评论回复
板凳
yiy|  楼主 | 2019-12-6 17:14 | 只看该作者
所以按照这个编译器说明看,搞STM8应该也是OK的。

使用特权

评论回复
地板
yiy|  楼主 | 2019-12-6 17:15 | 只看该作者

使用特权

评论回复
5
yiy|  楼主 | 2019-12-6 17:22 | 只看该作者
什么是SDCC?
SDCC是可重定目标的,优化的标准C(ANSI C89,ISO C99,ISO C11)编译器套件,针对的是基于Intel MCS51的微处理器(8031、8032、8051、8052 等), Maxim(以前称为Dallas),DS80C390变体, 飞思卡尔(以前基于Motorola)基于HC08 (hc08,s08), 基于Zilog Z80的MCU (z80,z180,gbz80,Rabbit 2000/3000,Rabbit 3000A,TLCS-90),Padauk(pdk14,pdk15)和 STMicroelectronics STM8。支持Padauk(pdk13),Microchip PIC16和PIC18 目标的工作正在进行中 。可以将其重新定位为其他微处理器。

SDCC套件是从具有不同FOSS许可证的不同来源派生的几个组件的集合。SDCC编译器套件包括:

SDAS和sdld,一个retargettable汇编程序和连接,基于ASXXXX,由Alan鲍德温写入; (GPL)。
sdcpp 预处理器,基于GCC cpp ; (GPL)。
ucsim 模拟器,最初由Daniel Drotos编写;(GPL)。
sdcdb 源代码级调试器,最初由Sandeep Dutta编写;(GPL)。
sdbinutils 库归档实用程序,包括从GNU Binutils派生的sdar,sdranlib和sdnm;(GPL)
SDCC运行时库;(GPL + LE)。Pic设备库和头文件是从Microchip头文件(.inc)和链接程序脚本(.lkr)文件派生的。Microchip要求“头文件应声明它们仅可与可靠的Microchip设备一起使用”,这使它们与GPL不兼容。
gcc-test 回归测试,源自 gcc-testsuite;(未明确指定许可,但由于它是GCC的一部分,因此可能是GPL许可)
packihx ; (公共区域)
马克宾 ; (zlib / libpng许可证)
sdcc C编译器,最初由Sandeep Dutta编写;(GPL)。一些功能包括:
广泛的MCU特定语言扩展,可有效利用基础硬件。
一系列标准优化,例如全局子表达式消除,循环优化(循环不变式,归纳变量的强度降低和循环反转),恒定折叠和传播,复制传播,死代码消除以及“ switch”语句的跳转表。
MCU特定的优化,包括全局寄存器分配器。
适用于MCU的自适应后端,应该非常适合其他8位MCU
基于独立规则的窥视孔优化器。
完整的数据类型范围:char(8位,1字节),short(16位,2字节), int(16位,2字节),long(32位,4字节),long long(64位,8字节),浮点数(IEEE 4字节)和 _Bool / bool。
可以在函数中的任何位置添加内联汇编代码。
报告功能复杂性以帮助决定应在汇编器中重写的功能。
很好的自动回归测试选择。
SDCC最初由Sandeep Dutta编写,并根据GPL许可发布。自最初发布以来,已经进行了许多错误修复和改进。从1999年12月起,代码被移至SourceForge,所有“用户都变成开发人员”都可以访问同一源代码树。SDCC会不断更新,包括所有用户和开发人员的输入。

使用特权

评论回复
6
dongnanxibei| | 2019-12-6 21:29 | 只看该作者
stm8-sdcc-examples-master.zip (19.57 KB)


使用特权

评论回复
7
dongnanxibei| | 2019-12-6 21:30 | 只看该作者
blink: Simple "Hello World!" of MCUs. Basic GPIO output control (Blink internal LED)
uart: Simple "Hello World" UART output
timer-interrupt: Basic use of a timer (TIM2) and related interrupt
spi-out-max7219: Simple SPI output to MAX7219 controlled 8 digit 7-segment display
ds18b20: Temperature sensor on 1-Wire

使用特权

评论回复
8
dongnanxibei| | 2019-12-6 21:30 | 只看该作者
/* Simple "Hello World" UART output  */
#include <string.h>
#include <stdint.h>
#include "stm8.h"

/* Simple busy loop delay */
void delay(unsigned long count) {
    while (count--)
        nop();
}

int uart_write(const char *str) {
    char i;
    for(i = 0; i < strlen(str); i++) {
        while(!(UART1_SR & UART_SR_TXE)); // !Transmit data register empty
        UART1_DR = str[i];
    }
    return(i); // Bytes sent
}

int main(void)
{
    /* Set clock to full speed (16 Mhz) */
    CLK_CKDIVR = 0;

    // Setup UART1 (TX=D5)
    UART1_CR2 |= UART_CR2_TEN; // Transmitter enable
    // UART1_CR2 |= UART_CR2_REN; // Receiver enable
    UART1_CR3 &= ~(UART_CR3_STOP1 | UART_CR3_STOP2); // 1 stop bit
    // 9600 baud: UART_DIV = 16000000/9600 ~ 1667 = 0x0683
    UART1_BRR2 = 0x03; UART1_BRR1 = 0x68; // 0x0683 coded funky way (see ref manual)

    while(1) {
        uart_write("Hello World!\r\n");
        delay(400000L);
    }
}

使用特权

评论回复
9
dongnanxibei| | 2019-12-6 21:30 | 只看该作者
/*
* Blink a LED every second using timer TIM2 and its Update/Overflow interrupt
*/
#include <stdint.h>
#include "stm8.h"

/* Build in LED is in pin B5 (STM8S103 board) or D3 (STM8S003F3 board) */
#ifdef STM8S103
#define LED_PORT    PB
#define LED_PIN     PIN5
#else
#define LED_PORT    PD
#define LED_PIN     PIN3
#endif

/* TIM2 Update/Overflow interrupt handling routine */
void TIM2_update(void) __interrupt(TIM2_OVR_UIF_IRQ) {
    // Blink internal LED. Port B (or D) output data register. Flip pin 5 (or 3)
    PORT(LED_PORT, ODR) ^= LED_PIN;

    // Clear Timer 2 Status Register 1 Update Interrupt Flag (UIF) (bit 0)
    TIM2_SR1 &= ~TIM_SR1_UIF;
}

int main(void)
{
    /* Set clock to full speed (16 Mhz) */
    CLK_CKDIVR = 0;

    /* GPIO of LED pin setup */
    // Set pin data direction as output
    PORT(LED_PORT, DDR)  |= LED_PIN; // i.e. PB_DDR |= (1 << 5);
    // Set pin as "Push-pull"
    PORT(LED_PORT, CR1)  |= LED_PIN; // i.e. PB_CR1 |= (1 << 5);

    /* TIM2 setup */
    // Prescaler register
    TIM2_PSCR = 14; // 2^14==16384, 16MHz/16384==976.5625 Hz
    // set Counter Auto-Reload Registers - TIM2_ARR=977 == 0x03D1, about once per second
    TIM2_ARRH = 0x03;
    TIM2_ARRL = 0xd1;
    // TIM2_IER (Interrupt Enable Register), Update interrupt (UIE) (bit 0)
    TIM2_IER |= TIM_IER_UIE;
    // TIM2_CR1 – Timer 2 Control Register 1, Counter ENable bit (CEN) (bit 0)
    TIM2_CR1 |= TIM_CR1_CEN;

    /* Loop infinitely waiting for an interrupt */
        while(1) {
        wfi();
    }
}

使用特权

评论回复
10
dongnanxibei| | 2019-12-6 21:31 | 只看该作者
/*
* 8 digit 7-segment LED display with MAX7219 controller chip
* DIN <-> C6 (MOSI)
* CS  <-> D2 (slave select)
* CLK <-> C5 (clock)
*/

#include <stdint.h>
#include "stm8.h"

/* Build in LED is in pin B5 (STM8S103 board) or D3 (STM8S003F3 board) */
#ifdef STM8S103
#define LED_PORT    PB
#define LED_PIN     PIN5
#else
#define LED_PORT    PD
#define LED_PIN     PIN3
#endif

/* TIM1 Update/Overflow interrupt handling routine */
void TIM1_update(void) __interrupt(TIM1_OVR_UIF_IRQ) {
    // Blink internal LED. Port B (or D) output data register. Flip pin 5 (or 3)
    PORT(LED_PORT, ODR) ^= LED_PIN;

    // Clear Timer Status Register 1 Update Interrupt Flag (UIF) (bit 0)
    TIM1_SR1 &= ~TIM_SR1_UIF;
}


void setup_spi() {
    // SPI port setup: MISO is pullup in, MOSI & SCK are push-pull out
    PC_DDR |= PIN5 | PIN6; // clock and MOSI
    PC_CR1 |= PIN5 | PIN6 | PIN7;

    // CS/SS (PD2) as output
    PD_DDR |= PIN2;
    PD_CR1 |= PIN2;
    PD_ODR |= PIN2; // CS high

    // SPI registers: First reset everything
    SPI_CR1 = 0;
    SPI_CR2 = 0;

    // SPI_CR1 LSBFIRST=0 (MSB is transmitted first)
    SPI_CR1 &= ~SPI_CR1_LSBFIRST;
    // Baud Rate Control: 0b111 = fmaster / 256 (62,500 baud)
    SPI_CR1 |= SPI_CR1_BR(0b111);
    // SPI_CR1 CPOL=0 (Clock Phase, The first clock transition is the first data capture edge)
    SPI_CR1 &= ~SPI_CR1_CPOL;
    // SPI_CR1 CPHA=0 (Clock Polarity, SCK to 0 when idle)
    SPI_CR1 &= ~SPI_CR1_CPHA;

    SPI_CR2 |= SPI_CR2_SSM; // bit 1 SSM=1 Software slave management, enabled
    SPI_CR2 |= SPI_CR2_SSI; // bit 0 SSI=1 Internal slave select, Master mode
    SPI_CR1 |= SPI_CR1_MSTR;  // CR1 bit 2 MSTR = 1, Master configuration.
}

uint8_t SPIOut(uint8_t data) {
    SPI_CR1 |= SPI_CR1_MSTR;;  // MSTR = 1, Master device.
    SPI_CR1 |= SPI_CR1_SPE; // SPE, SPI Enable, Peripheral enabled
    SPI_DR = data;
    while (SPI_SR & SPI_SR_BSY); // SPI is busy in communication or Tx buffer is not empty
    SPI_CR1 &= ~SPI_CR1_SPE; // Disable SPI
    data = SPI_DR;
    return data; // Not yet used.
}

void output_max(uint8_t address, uint8_t data) {
    PD_ODR &= ~PIN2; // CS low
    SPIOut(address);
    SPIOut(data);
    PD_ODR |= PIN2; // CS high
}

void init_max7219() {
    uint8_t i;
    output_max(0x0f, 0x00); //display test register - test mode off
    output_max(0x0c, 0x01); //shutdown register - normal operation
    output_max(0x0b, 0x07); //scan limit register - display digits 0 thru 7
    output_max(0x0a, 0x01); //intensity register (1 = 3/32 on.  0xf is max)
    output_max(0x09, 0xff); //decode mode register - CodeB decode all digits
    // Blank all digits
    for (i=1; i <= 8; i++) {
        output_max(i, 0xf);
    }
}

void display_number(uint32_t number) {
    uint8_t pos=1;
    if (number == 0)
        output_max(pos++, 0);
    while (number > 0) {
        uint8_t digit = number % 10;
        output_max(pos++, digit);
        number /= 10;
    }
    // clear rest of digits
    while (pos <= 8) {
        output_max(pos++, 0xf);
    }
}

int main(void)
{
    uint32_t counter = 0;

    /* Set clock to full speed (16 Mhz) */
    CLK_CKDIVR = 0;

    // Setup internal LED
    PORT(LED_PORT, DDR)  |= LED_PIN;
    PORT(LED_PORT, CR1)  |= LED_PIN;

    setup_spi();
    init_max7219();

    /* TIM1 setup: Generate interrupt every 1000ms */
    TIM1_CR1 = 0;
    // Just for fun, let's count down (TIM1 can do that)
    TIM1_CR1 |= TIM_CR1_DIR;
    // Prescaler: divide clock with 16000 (0x3E7F + 1) (to 1ms)
    TIM1_PSCRH = 0x0E;
    TIM1_PSCRL = 0x7F;
    // Auto-reload registers. Count to 1000 (0x03E8)
    TIM1_ARRH = 0x13;
    TIM1_ARRL = 0xE8;
    // TIM1_IER (Interrupt Enable Register), Update interrupt (UIE) (bit 0)
    TIM1_IER |= TIM_IER_UIE;
    // TIM1_CR1 – Timer Control Register 1, Counter ENable bit (CEN) (bit 0)
    TIM1_CR1 |= TIM_CR1_CEN;

    /* Loop infinitely waiting for an interrupt */
    while(1) {
        wfi();
        display_number(counter++);
        if (counter > 99999999) // In case we are running this for years :-)
            counter = 0;
    }
}

使用特权

评论回复
11
dongnanxibei| | 2019-12-6 21:31 | 只看该作者
/*
* DS18B20 input to port D4
* 8 digit 7-segment LED display with MAX7219 controller chip
* DIN <-> C6 (MOSI)
* CS  <-> D2 (slave select)
* CLK <-> C5 (clock)
*/

#include <stdint.h>
#include "stm8.h"

/* 1-Wire (DS18B20 data) pin */
#define OW_PORT PA
#define OW_PIN  PIN3


/* Simple busy loop delay */
void delay(unsigned long count) {
    while (count--)
        nop();
}

/* For LED-display */
void setup_spi() {
    // SPI port setup: MISO is pullup in, MOSI & SCK are push-pull out
    PC_DDR |= PIN5 | PIN6; // clock and MOSI
    PC_CR1 |= PIN5 | PIN6 | PIN7;

    // CS/SS (PD2) as output
    PD_DDR |= PIN2;
    PD_CR1 |= PIN2;
    PD_ODR |= PIN2; // CS high

    // SPI registers: First reset everything
    SPI_CR1 = 0;
    SPI_CR2 = 0;

    // SPI_CR1 LSBFIRST=0 (MSB is transmitted first)
    SPI_CR1 &= ~SPI_CR1_LSBFIRST;
    // Baud Rate Control: 0b111 = fmaster / 256 (62,500 baud)
    SPI_CR1 |= SPI_CR1_BR(0b111);
    // SPI_CR1 CPOL=0 (Clock Phase, The first clock transition is the first data capture edge)
    SPI_CR1 &= ~SPI_CR1_CPOL;
    // SPI_CR1 CPHA=0 (Clock Polarity, SCK to 0 when idle)
    SPI_CR1 &= ~SPI_CR1_CPHA;

    SPI_CR2 |= SPI_CR2_SSM; // bit 1 SSM=1 Software slave management, enabled
    SPI_CR2 |= SPI_CR2_SSI; // bit 0 SSI=1 Internal slave select, Master mode
    SPI_CR1 |= SPI_CR1_MSTR;  // CR1 bit 2 MSTR = 1, Master configuration.
}

uint8_t SPIOut(uint8_t data) {
    SPI_CR1 |= SPI_CR1_MSTR;;  // MSTR = 1, Master device.
    SPI_CR1 |= SPI_CR1_SPE; // SPE, SPI Enable, Peripheral enabled
    SPI_DR = data;
    while (SPI_SR & SPI_SR_BSY); // SPI is busy in communication or Tx buffer is not empty
    SPI_CR1 &= ~SPI_CR1_SPE; // Disable SPI
    data = SPI_DR;
    return data; // Not yet used.
}

void output_max(uint8_t address, uint8_t data) {
    PD_ODR &= ~PIN2; // CS low
    SPIOut(address);
    SPIOut(data);
    PD_ODR |= PIN2; // CS high
}

void init_max7219() {
    uint8_t i;
    output_max(0x0f, 0x00); //display test register - test mode off
    output_max(0x0c, 0x01); //shutdown register - normal operation
    output_max(0x0b, 0x07); //scan limit register - display digits 0 thru 7
    output_max(0x0a, 0x01); //intensity register (1 = 3/32 on.  0xf is max)
    output_max(0x09, 0xff); //decode mode register - CodeB decode all digits
    // Blank all digits
    for (i=1; i <= 8; i++) {
        output_max(i, 0xf);
    }
}

void display_number_dot(uint32_t number, uint8_t dot_pos, uint8_t is_negative) {
    uint8_t pos=1;
    if (number == 0)
        output_max(pos++, 0);
    while (number > 0 || dot_pos >= pos) {
        uint8_t digit = number % 10;
        if (pos == dot_pos) {
            digit = digit | 0x80;
        }
        output_max(pos++, digit);
        number /= 10;
    }
    if (is_negative) {
        output_max(pos++, 0xa);
    }
    // clear rest of digits
    while (pos <= 8) {
        output_max(pos++, 0xf);
    }
}

/********************** OneWire/DS18B20 routines ***************************/
void delay_us(uint16_t i) {
    if (i < 9) { // FIXME: Really ugly
        nop();
        return;
    }
    TIM2_CNTRH = 0;
    TIM2_CNTRL = 0;
    TIM2_EGR = 0x01; // Update Generation
    while(1) {
        volatile uint16_t counter = (((TIM2_CNTRH) << 8) | TIM2_CNTRL);
        if (i-6 < counter)
            return;
    }
}

#define OW_INPUT_MODE()     PORT(OW_PORT,DDR) &= ~OW_PIN
#define OW_OUTPUT_MODE()    PORT(OW_PORT,DDR) |= OW_PIN
#define OW_LOW()            PORT(OW_PORT,ODR) &= ~OW_PIN
#define OW_HIGH()           PORT(OW_PORT,ODR) |= OW_PIN
#define OW_READ()           (PORT(OW_PORT,IDR) & OW_PIN)

void ow_pull_low(unsigned int us) {
    OW_OUTPUT_MODE();
    OW_LOW();
    delay_us(us);
    OW_INPUT_MODE();
}

void ow_write_byte(uint8_t out) {
    uint8_t i;
    for (i=0; i < 8; i++) {
        if ( out & ((uint8_t)1<<i) ) {
            // write 1
            ow_pull_low(1);
            delay_us(60);
        } else {
            // write 0
            ow_pull_low(60);
            delay_us(1);
        }
    }
}

uint8_t ow_read_byte() {
    uint8_t val = 0;
    uint8_t i;
    for (i=0; i < 8; i++) {
        ow_pull_low(1);
        delay_us(5);
        if (OW_READ()) {
            val |= ((uint8_t)1<<i);
        }
        delay_us(55);
    }
    return val;
}

unsigned int ow_init() {

    uint8_t input;

    ow_pull_low(480);
    delay_us(60);

    input = !OW_READ();
    delay_us(420);

    return input;
}

unsigned int ow_convert_temperature() {
    int cycles = 1; // For debugging purposes

    ow_write_byte(0x44); // Convert Temperature

    while (1) {
        ow_pull_low(1);
        delay_us(5);
        if (OW_READ()) {
            return cycles;
        }
        delay_us(55);
        cycles++;
    }
}

void display_ds_temperature(uint8_t high, uint8_t low) {
    uint8_t is_negative = 0;
    uint16_t decimals = 0; // 4 decimals (e.g. decimals 625 means 0.0625)
    uint16_t i;

    uint16_t temp = ((int16_t)high << 8) | low;
    if (temp & 0x8000) {
        is_negative = 1;
        temp = (~temp) + 1;
    }
    low = temp & 0x0f;
    temp = temp >> 4;

    // low[3:0] mean values 0.5,0.25,0.125 and 0.0625
    for (i=625; i <= 5000; i=i*2) {
        if (low & 0x01) {
            decimals += i;
        }
        low = low >> 1;
    }

    // Display temperature rounded to one decimal
    display_number_dot((temp*1000 + ((decimals+5)/10) + 50)/100, 2, is_negative);
}

void read_ds18b20() {
    uint8_t i;
    uint8_t scratchpad[9];

    if (ow_init()) {
        ow_write_byte(0xcc); // Skip ROM
        ow_convert_temperature();

        ow_init();
        ow_write_byte(0xcc); // Skip ROM
        ow_write_byte(0xbe); // Read Scratchpad
        for (i=0; i<9; i++) {
            scratchpad[i] = ow_read_byte();
        }

        display_ds_temperature(scratchpad[1], scratchpad[0]);

    } else {
        /* DS18B20 was not detected */
        output_max(0x8, 0xa);
    }
}

/***************************************************************************/



int main(void)
{
    /* Set clock to full speed (16 Mhz) */
    CLK_CKDIVR = 0;

    // Timer setup (for delay_us)
    TIM2_PSCR = 0x4; // Prescaler: to 1MHz
    TIM2_CR1 |= TIM_CR1_CEN; // Start timer

    setup_spi();
    init_max7219();

    while(1) {
        read_ds18b20();
        delay(10000L);
    }
}

使用特权

评论回复
12
dongnanxibei| | 2019-12-6 21:31 | 只看该作者
/* The "Hello world!" of microcontrollers. Blink LED on/off */
#include <stdint.h>
#include "stm8.h"


/* Build in LED is in pin B5 (STM8S103 board) or D3 (STM8S003F3 board) */
#ifdef STM8S103
#define LED_PORT    PB
#define LED_PIN     PIN5
#else
#define LED_PORT    PD
#define LED_PIN     PIN3
#endif

/* Simple busy loop delay */
void delay(unsigned long count) {
    while (count--)
        nop();
}

int main(void)
{
    /* Set clock to full speed (16 Mhz) */
    CLK_CKDIVR = 0;

    /* GPIO setup */
    // Set pin data direction as output
    PORT(LED_PORT, DDR)  |= LED_PIN; // i.e. PB_DDR |= (1 << 5);
    // Set pin as "Push-pull"
    PORT(LED_PORT, CR1)  |= LED_PIN; // i.e. PB_CR1 |= (1 << 5);

        while(1) {
        // LED on
        PORT(LED_PORT, ODR) |= LED_PIN; // PB_ODR |= (1 << 5);
        delay(100000L);
        // LED off
        PORT(LED_PORT, ODR) &= ~LED_PIN; // PB_ODR &= ~(1 << 5);
        delay(300000L);
    }
}

使用特权

评论回复
13
dongnanxibei| | 2019-12-6 21:32 | 只看该作者
/*
* Analog input to port D4
* 8 digit 7-segment LED display with MAX7219 controller chip
* DIN <-> C6 (MOSI)
* CS  <-> D2 (slave select)
* CLK <-> C5 (clock)
*/

#include <stdint.h>
#include "stm8.h"

/* Simple busy loop delay */
void delay(unsigned long count) {
    while (count--)
        nop();
}

void init_adc() {
    ADC_CSR = 0;
    ADC_CR1 = 0;
    ADC_CR2 = 0;
    ADC_CR3 = 0;

/*
    ADC_DRH = 0;
    ADC_DRL = 0;
    ADC_TDRH = 0;
    ADC_TDRL = 0;
    ADC_HTRH = 0;
    ADC_HTRL = 0;
    ADC_LTRH = 0;
    ADC_LTRL = 0;
    ADC_AWSRH = 0;
    ADC_AWSRL = 0;
    ADC_AWCRH = 0;
    ADC_AWCRL = 0;
*/
    ADC_CSR = 2; // Select channel 2 (AIN2=PC4)

    ADC_CR1 |= ADC_CR1_ADON; // ADON
    ADC_CR2 &= ~ADC_CR2_ALIGN; // Align left

    delay(1000); // Give little time to be ready for first conversion
}

uint16_t analog_read() {
    ADC_CR1 &= ~ADC_CR1_CONT; // Single conversion mode
    ADC_CR1 |= ADC_CR1_ADON; // Start conversion
    do { nop(); } while ((ADC_CSR >> 7) == 0);
    ADC_CSR &= ~ADC_CSR_EOC; // Clear "End of conversion"-flag
    return (ADC_DRH << 2) | (ADC_DRL >> 6);  // Left aligned
}

/* For LED-display */
void setup_spi() {
    // SPI port setup: MISO is pullup in, MOSI & SCK are push-pull out
    PC_DDR |= PIN5 | PIN6; // clock and MOSI
    PC_CR1 |= PIN5 | PIN6 | PIN7;

    // CS/SS (PD2) as output
    PD_DDR |= PIN2;
    PD_CR1 |= PIN2;
    PD_ODR |= PIN2; // CS high

    // SPI registers: First reset everything
    SPI_CR1 = 0;
    SPI_CR2 = 0;

    // SPI_CR1 LSBFIRST=0 (MSB is transmitted first)
    SPI_CR1 &= ~SPI_CR1_LSBFIRST;
    // Baud Rate Control: 0b111 = fmaster / 256 (62,500 baud)
    SPI_CR1 |= SPI_CR1_BR(0b111);
    // SPI_CR1 CPOL=0 (Clock Phase, The first clock transition is the first data capture edge)
    SPI_CR1 &= ~SPI_CR1_CPOL;
    // SPI_CR1 CPHA=0 (Clock Polarity, SCK to 0 when idle)
    SPI_CR1 &= ~SPI_CR1_CPHA;

    SPI_CR2 |= SPI_CR2_SSM; // bit 1 SSM=1 Software slave management, enabled
    SPI_CR2 |= SPI_CR2_SSI; // bit 0 SSI=1 Internal slave select, Master mode
    SPI_CR1 |= SPI_CR1_MSTR;  // CR1 bit 2 MSTR = 1, Master configuration.
}

uint8_t SPIOut(uint8_t data) {
    SPI_CR1 |= SPI_CR1_MSTR;;  // MSTR = 1, Master device.
    SPI_CR1 |= SPI_CR1_SPE; // SPE, SPI Enable, Peripheral enabled
    SPI_DR = data;
    while (SPI_SR & SPI_SR_BSY); // SPI is busy in communication or Tx buffer is not empty
    SPI_CR1 &= ~SPI_CR1_SPE; // Disable SPI
    data = SPI_DR;
    return data; // Not yet used.
}

void output_max(uint8_t address, uint8_t data) {
    PD_ODR &= ~PIN2; // CS low
    SPIOut(address);
    SPIOut(data);
    PD_ODR |= PIN2; // CS high
}

void init_max7219() {
    uint8_t i;
    output_max(0x0f, 0x00); //display test register - test mode off
    output_max(0x0c, 0x01); //shutdown register - normal operation
    output_max(0x0b, 0x07); //scan limit register - display digits 0 thru 7
    output_max(0x0a, 0x01); //intensity register (1 = 3/32 on.  0xf is max)
    output_max(0x09, 0xff); //decode mode register - CodeB decode all digits
    // Blank all digits
    for (i=1; i <= 8; i++) {
        output_max(i, 0xf);
    }
}

void display_number(uint32_t number) {
    uint8_t pos=1;
    if (number == 0)
        output_max(pos++, 0);
    while (number > 0) {
        uint8_t digit = number % 10;
        output_max(pos++, digit);
        number /= 10;
    }
    // clear rest of digits
    while (pos <= 8) {
        output_max(pos++, 0xf);
    }
}

int main(void)
{
    /* Set clock to full speed (16 Mhz) */
    CLK_CKDIVR = 0;

    init_adc();
    setup_spi();
    init_max7219();

    while(1) {
        display_number(analog_read());
        delay(100000L);
    }
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

yiy

104

主题

1779

帖子

4

粉丝