[STM8] 发现一个宝贝

[复制链接]
779|12
 楼主| yiy 发表于 2019-12-6 16:50 | 显示全部楼层 |阅读模式
247945dea161b92112.png
https://jaist.dl.sourceforge.net/project/sdcc/sdcc-win32/3.9.0/sdcc-3.9.0-setup.exe
我先试试怎么用,好用了,再来分享刚才一不小心发现的。
 楼主| yiy 发表于 2019-12-6 17:14 | 显示全部楼层
  1. /*
  2. */

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

  5. void main(void)
  6. {
  7. int i;
  8. P2=0x01;
  9. delay(500);
  10. while(1)
  11. {
  12.   for(i=0;i<7;i++)
  13.   {
  14.      P2<<=1;
  15.      delay(500);
  16.   }
  17.    P2=0x01;
  18. delay(500);
  19. }
  20. }
  21. void delay(int x)
  22. {
  23.    int i,j;
  24.    for(i=x;i>0l;i--)
  25.      for(j=110;j>0;j--);
  26. }
512775dea1bcfb9eb9.png
145985dea1bd96a09e.png
先写了个51的跑马灯,非常的OK。
 楼主| yiy 发表于 2019-12-6 17:14 | 显示全部楼层
所以按照这个编译器说明看,搞STM8应该也是OK的。
 楼主| yiy 发表于 2019-12-6 17:15 | 显示全部楼层
 楼主| 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会不断更新,包括所有用户和开发人员的输入。
dongnanxibei 发表于 2019-12-6 21:29 | 显示全部楼层
stm8-sdcc-examples-master.zip (19.57 KB, 下载次数: 2)


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
dongnanxibei 发表于 2019-12-6 21:30 | 显示全部楼层
  1. /* Simple "Hello World" UART output  */
  2. #include <string.h>
  3. #include <stdint.h>
  4. #include "stm8.h"

  5. /* Simple busy loop delay */
  6. void delay(unsigned long count) {
  7.     while (count--)
  8.         nop();
  9. }

  10. int uart_write(const char *str) {
  11.     char i;
  12.     for(i = 0; i < strlen(str); i++) {
  13.         while(!(UART1_SR & UART_SR_TXE)); // !Transmit data register empty
  14.         UART1_DR = str[i];
  15.     }
  16.     return(i); // Bytes sent
  17. }

  18. int main(void)
  19. {
  20.     /* Set clock to full speed (16 Mhz) */
  21.     CLK_CKDIVR = 0;

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

  28.     while(1) {
  29.         uart_write("Hello World!\r\n");
  30.         delay(400000L);
  31.     }
  32. }
dongnanxibei 发表于 2019-12-6 21:30 | 显示全部楼层
  1. /*
  2. * Blink a LED every second using timer TIM2 and its Update/Overflow interrupt
  3. */
  4. #include <stdint.h>
  5. #include "stm8.h"

  6. /* Build in LED is in pin B5 (STM8S103 board) or D3 (STM8S003F3 board) */
  7. #ifdef STM8S103
  8. #define LED_PORT    PB
  9. #define LED_PIN     PIN5
  10. #else
  11. #define LED_PORT    PD
  12. #define LED_PIN     PIN3
  13. #endif

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

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

  21. int main(void)
  22. {
  23.     /* Set clock to full speed (16 Mhz) */
  24.     CLK_CKDIVR = 0;

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

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

  40.     /* Loop infinitely waiting for an interrupt */
  41.         while(1) {
  42.         wfi();
  43.     }
  44. }
dongnanxibei 发表于 2019-12-6 21:31 | 显示全部楼层
  1. /*
  2. * 8 digit 7-segment LED display with MAX7219 controller chip
  3. * DIN <-> C6 (MOSI)
  4. * CS  <-> D2 (slave select)
  5. * CLK <-> C5 (clock)
  6. */

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

  9. /* Build in LED is in pin B5 (STM8S103 board) or D3 (STM8S003F3 board) */
  10. #ifdef STM8S103
  11. #define LED_PORT    PB
  12. #define LED_PIN     PIN5
  13. #else
  14. #define LED_PORT    PD
  15. #define LED_PIN     PIN3
  16. #endif

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

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


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

  28.     // CS/SS (PD2) as output
  29.     PD_DDR |= PIN2;
  30.     PD_CR1 |= PIN2;
  31.     PD_ODR |= PIN2; // CS high

  32.     // SPI registers: First reset everything
  33.     SPI_CR1 = 0;
  34.     SPI_CR2 = 0;

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

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

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

  56. void output_max(uint8_t address, uint8_t data) {
  57.     PD_ODR &= ~PIN2; // CS low
  58.     SPIOut(address);
  59.     SPIOut(data);
  60.     PD_ODR |= PIN2; // CS high
  61. }

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

  74. void display_number(uint32_t number) {
  75.     uint8_t pos=1;
  76.     if (number == 0)
  77.         output_max(pos++, 0);
  78.     while (number > 0) {
  79.         uint8_t digit = number % 10;
  80.         output_max(pos++, digit);
  81.         number /= 10;
  82.     }
  83.     // clear rest of digits
  84.     while (pos <= 8) {
  85.         output_max(pos++, 0xf);
  86.     }
  87. }

  88. int main(void)
  89. {
  90.     uint32_t counter = 0;

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

  93.     // Setup internal LED
  94.     PORT(LED_PORT, DDR)  |= LED_PIN;
  95.     PORT(LED_PORT, CR1)  |= LED_PIN;

  96.     setup_spi();
  97.     init_max7219();

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

  112.     /* Loop infinitely waiting for an interrupt */
  113.     while(1) {
  114.         wfi();
  115.         display_number(counter++);
  116.         if (counter > 99999999) // In case we are running this for years :-)
  117.             counter = 0;
  118.     }
  119. }
dongnanxibei 发表于 2019-12-6 21:31 | 显示全部楼层
  1. /*
  2. * DS18B20 input to port D4
  3. * 8 digit 7-segment LED display with MAX7219 controller chip
  4. * DIN <-> C6 (MOSI)
  5. * CS  <-> D2 (slave select)
  6. * CLK <-> C5 (clock)
  7. */

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

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


  13. /* Simple busy loop delay */
  14. void delay(unsigned long count) {
  15.     while (count--)
  16.         nop();
  17. }

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

  23.     // CS/SS (PD2) as output
  24.     PD_DDR |= PIN2;
  25.     PD_CR1 |= PIN2;
  26.     PD_ODR |= PIN2; // CS high

  27.     // SPI registers: First reset everything
  28.     SPI_CR1 = 0;
  29.     SPI_CR2 = 0;

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

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

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

  51. void output_max(uint8_t address, uint8_t data) {
  52.     PD_ODR &= ~PIN2; // CS low
  53.     SPIOut(address);
  54.     SPIOut(data);
  55.     PD_ODR |= PIN2; // CS high
  56. }

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

  69. void display_number_dot(uint32_t number, uint8_t dot_pos, uint8_t is_negative) {
  70.     uint8_t pos=1;
  71.     if (number == 0)
  72.         output_max(pos++, 0);
  73.     while (number > 0 || dot_pos >= pos) {
  74.         uint8_t digit = number % 10;
  75.         if (pos == dot_pos) {
  76.             digit = digit | 0x80;
  77.         }
  78.         output_max(pos++, digit);
  79.         number /= 10;
  80.     }
  81.     if (is_negative) {
  82.         output_max(pos++, 0xa);
  83.     }
  84.     // clear rest of digits
  85.     while (pos <= 8) {
  86.         output_max(pos++, 0xf);
  87.     }
  88. }

  89. /********************** OneWire/DS18B20 routines ***************************/
  90. void delay_us(uint16_t i) {
  91.     if (i < 9) { // FIXME: Really ugly
  92.         nop();
  93.         return;
  94.     }
  95.     TIM2_CNTRH = 0;
  96.     TIM2_CNTRL = 0;
  97.     TIM2_EGR = 0x01; // Update Generation
  98.     while(1) {
  99.         volatile uint16_t counter = (((TIM2_CNTRH) << 8) | TIM2_CNTRL);
  100.         if (i-6 < counter)
  101.             return;
  102.     }
  103. }

  104. #define OW_INPUT_MODE()     PORT(OW_PORT,DDR) &= ~OW_PIN
  105. #define OW_OUTPUT_MODE()    PORT(OW_PORT,DDR) |= OW_PIN
  106. #define OW_LOW()            PORT(OW_PORT,ODR) &= ~OW_PIN
  107. #define OW_HIGH()           PORT(OW_PORT,ODR) |= OW_PIN
  108. #define OW_READ()           (PORT(OW_PORT,IDR) & OW_PIN)

  109. void ow_pull_low(unsigned int us) {
  110.     OW_OUTPUT_MODE();
  111.     OW_LOW();
  112.     delay_us(us);
  113.     OW_INPUT_MODE();
  114. }

  115. void ow_write_byte(uint8_t out) {
  116.     uint8_t i;
  117.     for (i=0; i < 8; i++) {
  118.         if ( out & ((uint8_t)1<<i) ) {
  119.             // write 1
  120.             ow_pull_low(1);
  121.             delay_us(60);
  122.         } else {
  123.             // write 0
  124.             ow_pull_low(60);
  125.             delay_us(1);
  126.         }
  127.     }
  128. }

  129. uint8_t ow_read_byte() {
  130.     uint8_t val = 0;
  131.     uint8_t i;
  132.     for (i=0; i < 8; i++) {
  133.         ow_pull_low(1);
  134.         delay_us(5);
  135.         if (OW_READ()) {
  136.             val |= ((uint8_t)1<<i);
  137.         }
  138.         delay_us(55);
  139.     }
  140.     return val;
  141. }

  142. unsigned int ow_init() {

  143.     uint8_t input;

  144.     ow_pull_low(480);
  145.     delay_us(60);

  146.     input = !OW_READ();
  147.     delay_us(420);

  148.     return input;
  149. }

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

  152.     ow_write_byte(0x44); // Convert Temperature

  153.     while (1) {
  154.         ow_pull_low(1);
  155.         delay_us(5);
  156.         if (OW_READ()) {
  157.             return cycles;
  158.         }
  159.         delay_us(55);
  160.         cycles++;
  161.     }
  162. }

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

  167.     uint16_t temp = ((int16_t)high << 8) | low;
  168.     if (temp & 0x8000) {
  169.         is_negative = 1;
  170.         temp = (~temp) + 1;
  171.     }
  172.     low = temp & 0x0f;
  173.     temp = temp >> 4;

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

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

  184. void read_ds18b20() {
  185.     uint8_t i;
  186.     uint8_t scratchpad[9];

  187.     if (ow_init()) {
  188.         ow_write_byte(0xcc); // Skip ROM
  189.         ow_convert_temperature();

  190.         ow_init();
  191.         ow_write_byte(0xcc); // Skip ROM
  192.         ow_write_byte(0xbe); // Read Scratchpad
  193.         for (i=0; i<9; i++) {
  194.             scratchpad[i] = ow_read_byte();
  195.         }

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

  197.     } else {
  198.         /* DS18B20 was not detected */
  199.         output_max(0x8, 0xa);
  200.     }
  201. }

  202. /***************************************************************************/



  203. int main(void)
  204. {
  205.     /* Set clock to full speed (16 Mhz) */
  206.     CLK_CKDIVR = 0;

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

  210.     setup_spi();
  211.     init_max7219();

  212.     while(1) {
  213.         read_ds18b20();
  214.         delay(10000L);
  215.     }
  216. }
dongnanxibei 发表于 2019-12-6 21:31 | 显示全部楼层
  1. /* The "Hello world!" of microcontrollers. Blink LED on/off */
  2. #include <stdint.h>
  3. #include "stm8.h"


  4. /* Build in LED is in pin B5 (STM8S103 board) or D3 (STM8S003F3 board) */
  5. #ifdef STM8S103
  6. #define LED_PORT    PB
  7. #define LED_PIN     PIN5
  8. #else
  9. #define LED_PORT    PD
  10. #define LED_PIN     PIN3
  11. #endif

  12. /* Simple busy loop delay */
  13. void delay(unsigned long count) {
  14.     while (count--)
  15.         nop();
  16. }

  17. int main(void)
  18. {
  19.     /* Set clock to full speed (16 Mhz) */
  20.     CLK_CKDIVR = 0;

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

  26.         while(1) {
  27.         // LED on
  28.         PORT(LED_PORT, ODR) |= LED_PIN; // PB_ODR |= (1 << 5);
  29.         delay(100000L);
  30.         // LED off
  31.         PORT(LED_PORT, ODR) &= ~LED_PIN; // PB_ODR &= ~(1 << 5);
  32.         delay(300000L);
  33.     }
  34. }
dongnanxibei 发表于 2019-12-6 21:32 | 显示全部楼层
  1. /*
  2. * Analog input to port D4
  3. * 8 digit 7-segment LED display with MAX7219 controller chip
  4. * DIN <-> C6 (MOSI)
  5. * CS  <-> D2 (slave select)
  6. * CLK <-> C5 (clock)
  7. */

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

  10. /* Simple busy loop delay */
  11. void delay(unsigned long count) {
  12.     while (count--)
  13.         nop();
  14. }

  15. void init_adc() {
  16.     ADC_CSR = 0;
  17.     ADC_CR1 = 0;
  18.     ADC_CR2 = 0;
  19.     ADC_CR3 = 0;

  20. /*
  21.     ADC_DRH = 0;
  22.     ADC_DRL = 0;
  23.     ADC_TDRH = 0;
  24.     ADC_TDRL = 0;
  25.     ADC_HTRH = 0;
  26.     ADC_HTRL = 0;
  27.     ADC_LTRH = 0;
  28.     ADC_LTRL = 0;
  29.     ADC_AWSRH = 0;
  30.     ADC_AWSRL = 0;
  31.     ADC_AWCRH = 0;
  32.     ADC_AWCRL = 0;
  33. */
  34.     ADC_CSR = 2; // Select channel 2 (AIN2=PC4)

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

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

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

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

  51.     // CS/SS (PD2) as output
  52.     PD_DDR |= PIN2;
  53.     PD_CR1 |= PIN2;
  54.     PD_ODR |= PIN2; // CS high

  55.     // SPI registers: First reset everything
  56.     SPI_CR1 = 0;
  57.     SPI_CR2 = 0;

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

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

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

  79. void output_max(uint8_t address, uint8_t data) {
  80.     PD_ODR &= ~PIN2; // CS low
  81.     SPIOut(address);
  82.     SPIOut(data);
  83.     PD_ODR |= PIN2; // CS high
  84. }

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

  97. void display_number(uint32_t number) {
  98.     uint8_t pos=1;
  99.     if (number == 0)
  100.         output_max(pos++, 0);
  101.     while (number > 0) {
  102.         uint8_t digit = number % 10;
  103.         output_max(pos++, digit);
  104.         number /= 10;
  105.     }
  106.     // clear rest of digits
  107.     while (pos <= 8) {
  108.         output_max(pos++, 0xf);
  109.     }
  110. }

  111. int main(void)
  112. {
  113.     /* Set clock to full speed (16 Mhz) */
  114.     CLK_CKDIVR = 0;

  115.     init_adc();
  116.     setup_spi();
  117.     init_max7219();

  118.     while(1) {
  119.         display_number(analog_read());
  120.         delay(100000L);
  121.     }
  122. }
您需要登录后才可以回帖 登录 | 注册

本版积分规则

yiy

114

主题

1954

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部