16+
Пятница
19 января
Вход |Карта сайта | |Upload |codebook | PARTS

 О смысле всего сущего 0xFF

 Средства и методы разработки

 Мобильная и беспроводная связь

 Блошиный рынок Объявления

caxapa

Микроконтроллеры ARM 

AVR PIC MSP PLD,FPGA,DSP 

Кибернетика Технологии 

Схемы, платы, компоненты 

Микроконтроллеры

 
   Новая тема Правила Регистрация Поиск »» Архив
Вернуться в конференциюТопик полностью
Гyдвин  (20.11.2017 15:23) , в ответ на Вступил, йопть, в STM8. Сразу такая граблЯ - пин PD1 порта D после сброса используется для SWIM. Любая запись в регистр DDR порта, вырубает отладку. Бит 1, естественно,=0. Извечный русский вопрос к уже вступившим: Кто виноват и что делать? Отладка автор: Гyдвин
Вступил. Вполне даже неплох этот STM8, если прикрыть глаза на французские шалости. Понравилась отладка. Шустрая, много точек останова. Даже в таком мелком чипе. Отладчики MSP, AVR и PIC отдыхают. Внутри история болезни и стационарного лечения ;) 
Может кому пригодится:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Пациент - китайский идикатор напряжения и тока на STM8 в ssop20
// Место жительства: ru.aliexpress.com/cp/voltmeter-ammeter-online-shopping.html
//
// Анамнез: бред, навязчибые попытки показывать "направление на Пентагон","погоду за бортом" вместо исполнения штатных
обязанностей.
//
// Дагноз: идиотские делители в каналах измерения, использование малого участка диапазона встроенного АЦП. 
// Положительные моменты - пациет немного кушает при достаточно ярком индикаторе, имеет стабилизатор/опору с неплохими
характеристиками.
//
// Операционное вмешательство: 
// Пересадка LM358 на r2r output MCP602 для увеличения диапазона выходного сигнала
// Замена/подгонка резисторов в делителе напряжения и обратной связи ОУ токового канала
// с целью нормировать входные сигналы к полному диапазону АЦП. 
//
// Консервативное реанимационное лечение:
// Не пинать! Интерн провел первую операцию на STM8.
// Говнокодие, ибо "шармоватое" распределение аж 4 портов в 16 пин в STM8S003F3 не позволяет "изобразить красиво"
// А может просто интерн не умеет их готовить - STM еще те затейники :)
// Ну и что китайцы выродили/развели, то и приходится лечить...
// Не пользовал прерывания. Ини пациету они в этом случае нафиг не нужны.
// Так проще выровнять яркость свечения знакомест индикаторов (красные/синие, нагрузочные способности портов).
// Инструменты:
// IAR v 1.4. Более старшие не ставятся на XP :(
// Оптимизация LOW или Medium.
// При оптимизации "High" IAR v1.4 делает даже этот простенький линейный код неработоспособным. Пациент дохнет :)
//
// Эпикриз: пациенту стало значительно лучше. 
//
// Амбулаторное лечение:
// Обратиться с светилам медицины ST для дальнейших консультаций и назначений.
// Есть возможность переучить для другого рода деятельности.
// Например, после несложной хирургии и лечения использовать как дешевый законченный встраиваемый индикатор 
// c последовательным интерфейсом. Ибо RX,TX  uart разведены на разъем.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


#include "stm8s.h"
#include <stdio.h>


//для выравнивания яркости знакомест
#define DELAY      600   // время индикации символа разрядов 1..3 
#define DELAY1     500   // время индикации символа разрядов 4..5 
#define DELAY2     800   // время индикации символа разряда  6    

#define N_AVERAGE  256   // количество замеров ADC для усреднения (д.б. кратно 2 и желательно степень 2)


unsigned int  cnt_adc; //
char           disp[8]=" 00000";

unsigned long adc_U;// сумма adc U для усреднения
unsigned long adc_I;// сумма adc I для усреднения
unsigned int  tmp_i;// для процедуры калибровки смещения ОУ в канале измерения тока
unsigned int  sav_i;// для установки позиции точки индикатора тока

uint16_t *zero_I = (uint16_t *)0x4000; // калибровка начального смещения ОУ тока в EEPROM 


void delay(long t)
{
    long i;
    for (i = 0;i < t;i++);
}

void work_adc(void)
{
    unsigned int  tmp;
    ADC1->CSR = 0x04;    // AIN4 (PD3) Канал напряжения
    ADC1->CR1 |= 0x01;   // start conversion
    while (!(ADC1->CSR & 0x80)); // wait for end of conversion
    tmp=  ADC1->DRL;
    tmp |=  (ADC1->DRH << 8);
    adc_U+=tmp;
    ADC1->CSR = 0x03; // AIN3 (PD2) Канал тока
    ADC1->CR1 |= 0x01;// start conversion
    while (!(ADC1->CSR & 0x80));    // wait for end of conversion
    tmp= ADC1->DRL;
    tmp |=  (ADC1->DRH << 8); 
    tmp_i=tmp;//  в tmp_i останется "сырое" значение тока после выполнения функции
    // компенсация смещения ОУ канала измерения тока
    if (tmp < *zero_I)  tmp=0; 
         else tmp= tmp - *zero_I; 
    adc_I+=tmp;
    cnt_adc++;
    if (cnt_adc==N_AVERAGE)
     {
       cnt_adc=0; 
       adc_U= adc_U/N_AVERAGE;      // вычисляем среднее напряжения 
       adc_U/=4; //масштабируем значение напряжения для вывода на индикатор // 12V = 480adc, max 25.575V = 1023adc  
       adc_I= adc_I/(N_AVERAGE/2);  // вычисляем среднее тока + масштабируем + некое повышение разрядности для вывода на
индикатор. 10A = 500adc*2 
       sav_i=adc_I; // запомним тасштабированное значение тока  
       sprintf(disp,"%03lu%03lu", adc_U,adc_I);
       if (disp[0]=='0') disp[0]=' '; //удалим незначащий нуль 
       adc_I=0; // обнулим для следуюшего цикла
       adc_U=0;
     }
}

void out_7led_dig(char numb_dig)  // вывод очередного символа в 7LED из строки disp
{
  GPIOC->ODR&=  ~(1<<5); //PC5 (DP) // сотрем точку
  if (numb_dig == 1) GPIOC->ODR|=  (1<<5); //PC5 (DP) // выведем точку (напряжение)
  if ((sav_i < 1000)&&(numb_dig == 3)) GPIOC->ODR|=  (1<<5); //PC5 (DP) // выведем точку (ток <  10А)
  if ((sav_i > 999)&&(numb_dig == 4)) GPIOC->ODR|=  (1<<5); //PC5 (DP) // выведем точку (ток >= 10А) 
  
  switch (disp[numb_dig]) 
   { 
    case '0':
             GPIOD->ODR|=  (1<<1);  // PD1 (A)  
             GPIOA->ODR|=  (1<<3);  // PA3 (B)  
             GPIOC->ODR|=  (1<<3);  // PC3 (C)  
             GPIOC->ODR|=  (1<<6);  // PC6 (D)  
             GPIOC->ODR|=  (1<<7);  // PC7 (E)  
             GPIOC->ODR|=  (1<<4);  // PC4 (F)  
             GPIOA->ODR&=  ~(1<<2); // PA2 (G)  
             break;
    case '1':
             GPIOD->ODR&=  ~(1<<1); // PD1 (A)  
             GPIOA->ODR|=  (1<<3);  // PA3 (B)  
             GPIOC->ODR|=  (1<<3);  // PC3 (C)  
             GPIOC->ODR&=  ~(1<<6); // PC6 (D)  
             GPIOC->ODR&=  ~(1<<7); // PC7 (E)  
             GPIOC->ODR&=  ~(1<<4); // PC4 (F)  
             GPIOA->ODR&=  ~(1<<2); // PA2 (G)  
             break;
    case '2':
             GPIOD->ODR|=  (1<<1);  // PD1 (A)  
             GPIOA->ODR|=  (1<<3);  // PA3 (B)  
             GPIOC->ODR&=  ~(1<<3); // PC3 (C)  
             GPIOC->ODR|=  (1<<6);  // PC6 (D)  
             GPIOC->ODR|=  (1<<7);  // PC7 (E)  
             GPIOC->ODR&=  ~(1<<4); // PC4 (F)  
             GPIOA->ODR|=  (1<<2);  // PA2 (G)  
             break;
    case '3':
             GPIOD->ODR|=  (1<<1);  // PD1 (A)  
             GPIOA->ODR|=  (1<<3);  // PA3 (B)  
             GPIOC->ODR|=  (1<<3);  // PC3 (C)  
             GPIOC->ODR|=  (1<<6);  // PC6 (D)  
             GPIOC->ODR&=  ~(1<<7); // PC7 (E)  
             GPIOC->ODR&=  ~(1<<4); // PC4 (F)  
             GPIOA->ODR|=  (1<<2);  // PA2 (G)  
             break;
    case '4':
             GPIOD->ODR&=  ~(1<<1); // PD1 (A)  
             GPIOA->ODR|=  (1<<3);  // PA3 (B)  
             GPIOC->ODR|=  (1<<3);  // PC3 (C)  
             GPIOC->ODR&=  ~(1<<6); // PC6 (D)  
             GPIOC->ODR&=  ~(1<<7); // PC7 (E)  
             GPIOC->ODR|=  (1<<4);  // PC4 (F)  
             GPIOA->ODR|=  (1<<2);  // PA2 (G)  
             break;
    case '5':
             GPIOD->ODR|=  (1<<1);  // PD1 (A)  
             GPIOA->ODR&=  ~(1<<3); // PA3 (B)  
             GPIOC->ODR|=  (1<<3);  // PC3 (C)  
             GPIOC->ODR|=  (1<<6);  // PC6 (D)  
             GPIOC->ODR&=  ~(1<<7); // PC7 (E)  
             GPIOC->ODR|=  (1<<4);  // PC4 (F)  
             GPIOA->ODR|=  (1<<2);  // PA2 (G)  
             break;
    case '6':
             GPIOD->ODR|=  (1<<1);  // PD1 (A)  
             GPIOA->ODR&=  ~(1<<3); // PA3 (B)  
             GPIOC->ODR|=  (1<<3);  // PC3 (C)  
             GPIOC->ODR|=  (1<<6);  // PC6 (D)  
             GPIOC->ODR|=  (1<<7);  // PC7 (E)  
             GPIOC->ODR|=  (1<<4);  // PC4 (F)  
             GPIOA->ODR|=  (1<<2);  // PA2 (G)  
             break;
    case '7':
             GPIOD->ODR|=  (1<<1);  // PD1 (A)  
             GPIOA->ODR|=  (1<<3);  // PA3 (B)  
             GPIOC->ODR|=  (1<<3);  // PC3 (C)  
             GPIOC->ODR&=  ~(1<<6); // PC6 (D)  
             GPIOC->ODR&=  ~(1<<7); // PC7 (E)  
             GPIOC->ODR&=  ~(1<<4); // PC4 (F)  
             GPIOA->ODR&=  ~(1<<2); // PA2 (G)  
             break;
    case '8':
             GPIOD->ODR|=  (1<<1);  // PD1 (A)  
             GPIOA->ODR|=  (1<<3);  // PA3 (B)  
             GPIOC->ODR|=  (1<<3);  // PC3 (C)  
             GPIOC->ODR|=  (1<<6);  // PC6 (D)  
             GPIOC->ODR|=  (1<<7);  // PC7 (E)  
             GPIOC->ODR|=  (1<<4);  // PC4 (F)  
             GPIOA->ODR|=  (1<<2);  // PA2 (G)  
             break;
    case '9':
             GPIOD->ODR|=  (1<<1);  // PD1 (A)  
             GPIOA->ODR|=  (1<<3);  // PA3 (B)  
             GPIOC->ODR|=  (1<<3);  // PC3 (C)  
             GPIOC->ODR|=  (1<<6);  // PC6 (D)  
             GPIOC->ODR&=  ~(1<<7); // PC7 (E)  
             GPIOC->ODR|=  (1<<4);  // PC4 (F)  
             GPIOA->ODR|=  (1<<2);  // PA2 (G)  
             break;
    default:
             GPIOD->ODR&=  ~(1<<1); // PD1 (A)  
             GPIOA->ODR&=  ~(1<<3); // PA3 (B)  
             GPIOC->ODR&=  ~(1<<3); // PC3 (C)  
             GPIOC->ODR&=  ~(1<<6); // PC6 (D)  
             GPIOC->ODR&=  ~(1<<7); // PC7 (E)  
             GPIOC->ODR&=  ~(1<<4); // PC4 (F)  
             GPIOA->ODR&=  ~(1<<2); // PA2 (G)  
             break;
   }  
}


void main(void)
{
  
  CLK->CKDIVR = 0x00;  // 16MHz 
  
  CFG->GCR |= CFG_GCR_SWD; // отключим SWIM

  // Set ADC 
  ADC1->CR1 = 0x40; //Fadc = Fmaster/8 = 2MHz
  ADC1->CR2 = 0x08; //Right alignement
  ADC1->CR1 |= 0x01; // ADC on

  GPIOD->CR1|= (1<<6); // подтянем PD6 к VDD (это контакт перемычки)
  delay(100);  // задержка стабилизации ADC 
  
  // процедура калибровки смещения ОУ канала измерения тока при включении
  if (!(GPIOD->IDR & (1<<6))) // если установлена перемычка (как в китайском оригинале) при включении, запоминаем в
EEPROM смещение ОУ "zero_I". При отсутствии тока! 
   {
    work_adc();
    work_adc();
    FLASH->DUKR = 0xAE;
    FLASH->DUKR = 0x56; 
    *zero_I=tmp_i;
    delay(90000);  
    while (!(GPIOD->IDR & (1<<6))) delay(10000);  
    IWDG->KR = IWDG_KEY_ENABLE; // Пересброс по WDT
    while ( 1 );    
   }

  
  // Set GPIO  
  GPIOB->DDR = 0xFF;
  GPIOB->CR1 = 0xFF;
  
  GPIOA->DDR = 0xFF;
  GPIOA->CR1 = 0xFF;

  GPIOC->DDR = 0xFF;
  GPIOC->CR1 = 0xFF;
  
  GPIOD->DDR = 0x72; // 0111 0010 // PD3,PD2 - вxоды ADC 
  GPIOD->CR1 = 0x72; // 0111 0010 // PD3,PD2 - вxоды ADC 

 
  GPIOD->ODR|=  (1<<4); // PD4 = 1 (0) // общие катоды всех знакомест 7LED (столбцы)
  GPIOD->ODR|=  (1<<6); // PD6 = 1 (1) 
  GPIOD->ODR|=  (1<<5); // PD5 = 1 (2) 
  GPIOB->ODR|=  (1<<5); // PB5 = 1 (3)
  GPIOB->ODR|=  (1<<4); // PB4 = 1 (4) 
  GPIOA->ODR|=  (1<<1); // PA1 = 1 (5) 
  
  
  while (1) // цикл по знакоместам
  {
    //disp[0] 
    work_adc();
      GPIOD->ODR&= ~(1<<4); // PD4 = 0
    out_7led_dig(0);
    delay(DELAY);
      GPIOD->ODR|= (1<<4);  // PD4 = 1

    //disp[1] 
    work_adc();
      GPIOD->ODR&=  ~(1<<6); // PD6 = 0
    out_7led_dig(1);
    delay(DELAY);
      GPIOD->ODR|=  (1<<6); // PD6 = 1
        
    //disp[2] 
    work_adc();
      GPIOD->ODR&=  ~(1<<5); // PD5 = 0
    out_7led_dig(2);
    delay(DELAY);
      GPIOD->ODR|=  (1<<5); // PD5 = 1

    //disp[3] 
    work_adc();
      GPIOB->ODR&=  ~(1<<5); // PB5 = 0
    out_7led_dig(3);
    delay(DELAY1);
      GPIOB->ODR|=  (1<<5); // PB5 = 1

    //disp[4] 
    work_adc();
      GPIOB->ODR&=  ~(1<<4); // PB4 = 0
    out_7led_dig(4);
    delay(DELAY1);
      GPIOB->ODR|=  (1<<4); // PB4 = 1
      
    //disp[5] 
    work_adc();
      GPIOA->ODR&=  ~(1<<1); // PA1 = 0
    out_7led_dig(5);
    delay(DELAY2);
      GPIOA->ODR|=  (1<<1); // PA1 = 1
  }
}
Главная | Карта сайта | О проекте | Проекты | Файлообменник | Регистрация | Вебмастер | RSS
Лето 7526 от сотворения мира. При использовании материалов сайта ссылка на caxapу обязательна.
MMI © MMXVIII