реклама на сайте
подробности

 
 
> ST Visual Develop для STM8 и математические функции
zheka
сообщение Aug 11 2018, 08:59
Сообщение #1


Гуру
******

Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164



Господа, понадобилось мне разбить число float для вывода на сегментный индикатор (на целую и дробную части). Залез я в какой-то проект старый для STM32, где у меня это было реализовано - ан нет, не работает, библиотека math.h нужна.
А а ST Visual Development нету такой.
Попытался кормить ему тот файл, что в Keil - компилятор им подавился. Около сотни ошибок, подавляющее большинство из них - "not an argument"

Собственно вопросы - кто-нибудь пытался вставить библиотеки от KEIL в ST Visual Development?
Может в STVD есть свои математические функции?

Если нет, то как протыми средствами C разделить float на челую и дробную (до двух знаков) части?

Попробовал написать свою функцию, точностью до одного знака после запятой.

Код
void LCD_Show_Current(float current)
{

    int int_num, decimal_num;
    float decimal_part;
    
    int_num=current;
        decimal_part=current-int_num;

    decimal_num=decimal_part*10;
}


Результат странный - decimal part почему-то всегда меньше на 0.1 (соответственно decimal_num меньше на единицу).

В функцию число поступает правильное (проверял уже внутри функции). А вот после decimal_part=current-int_num; получается недостача.

В упор не вижу, где я ошибся?

Тихо сам с собою - когда присваиваю переменной значение скажем 13.7, в отладчике оказывается, что переменная равна 13.69999998....
Что за самодеятельность контроллера?

Сообщение отредактировал zheka - Aug 11 2018, 08:45
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
zheka
сообщение Aug 12 2018, 07:31
Сообщение #2


Гуру
******

Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164



Я использую COSMIC
Ну и нарисовалась очередная проблема...
Код
#error clnk Debug\ups_stm8_project.lkf:1 segment .text size overflow (1465)

Ковырялся в настройках, единственное, что сделал, так это поменял Memory Model на Long Stack. Не помогло.

Контроллер STM8S003F3P6 - флеша 8 кб, RAM - 1 кб
А программка то у меня небольшая, вряд ли, чтоб я успел вылезти за пределы памяти.

Посмотрите на код, может у меня нерационально как-то с переменными? Куда копать?


CODE

/* MAIN.C file
*
* Copyright © 2002-2005 STMicroelectronics
*/

#include "stm8s.h"
#include "stm8s_adc1.h"
#include "stm8s_clk.h"
#include "stm8s_tim1.h"

#define BACKLIGHT GPIO_PIN_3
#define BACKLIGHT_PORT GPIOA

#define TM1722_POWER GPIO_PIN_4
#define STB GPIO_PIN_5
#define SCLK GPIO_PIN_6
#define DIO GPIO_PIN_7

#define IO_PORT GPIOC

#define LATENCY 1


#define LED GPIO_PIN_5
#define LED_PORT GPIOB

unsigned char DIGITS[10]={0xFA,0x60,0xD6,0xF4,0x6C,0xBC,0xBE,0xE0,0xFE,0xFC};
unsigned char BATTERY_LEVELS[9]={0x00,0x10,0x11,0x19,0x1D,0x1F,0x3F,0x7F,0xFF};



typedef struct
{
float VOLTAGE;
float CURRENT;
float TEMPERATURE;
unsigned char PERCENT;
unsigned char BATTERY_LEVEL;
unsigned char SPARK_sign;
unsigned char current_right_parameter; // 0 - off, 1 -voltage, 2 - temperature
unsigned char current_left_parameter; // 0- off, 1 - percent, 2 - current

} tLCD_VAR;

tLCD_VAR LCD_VAR;


void delay(uint32_t t) {
while(--t);
}

volatile uint16_t adc2;

INTERRUPT_HANDLER(ADC1_IRQHandler,22)
{


ADC1_ClearITPendingBit(ADC1_IT_EOC);

adc2 = ADC1_GetBufferValue(ADC1_CHANNEL_4);
}

void send_command(unsigned char code)
{

uint8_t n;

GPIO_WriteHigh(IO_PORT, STB);
delay(LATENCY);
GPIO_WriteLow(IO_PORT, STB);
delay(LATENCY);
for (n=0;n<8;n++)
{
GPIO_WriteLow(IO_PORT, SCLK);
if ((code>>n)&0x01) GPIO_WriteHigh(IO_PORT, DIO); else GPIO_WriteLow(IO_PORT, DIO);
delay(LATENCY);
GPIO_WriteHigh(IO_PORT, SCLK);
delay(LATENCY);
}
delay(LATENCY);

}

void send_data(unsigned char code)
{
unsigned char n;

for (n=0;n<8;n++)
{
GPIO_WriteLow(IO_PORT, SCLK);
if ((code>>n)&0x01) GPIO_WriteHigh(IO_PORT, DIO); else GPIO_WriteLow(IO_PORT, DIO);
delay(LATENCY);
GPIO_WriteHigh(IO_PORT, SCLK);
delay(LATENCY);
}


}

void LCD_Clear(unsigned char a)
{
unsigned char x;
send_command(0x00);
send_command(0x40);
send_command(0x02);
for (x=0;x<16;x++) send_data(0x00);
send_command(0x97);
}

void LCD_Update()
{

}

void LCD_Show_Voltage(float voltage)
{
unsigned int int_num, decimal_num;
float decimal_part;
unsigned char percent_sign=0;

if (LCD_VAR.current_left_parameter==1) percent_sign=1;

voltage=voltage+0.01;
int_num=voltage;
decimal_num=(voltage-(int)voltage)*10;
send_command(0x00);
send_command(0x44);
send_command(0xC7);
if (int_num<10) send_data(0x00+percent_sign);else send_data(DIGITS[int_num/10]+percent_sign);
send_command(0xCB);
send_data(DIGITS[int_num%10]);
send_command(0xCE);
send_data(DIGITS[decimal_num]+1);
send_command(0xCA);
send_data(0x4);
send_command(0x97);
LCD_VAR.current_right_parameter=1;
}

void LCD_Show_Temperature(float temperature)
{
unsigned int int_num, decimal_num;
float decimal_part;
unsigned char percent_sign=0;

if (LCD_VAR.current_left_parameter==1) percent_sign=1;

temperature=temperature+0.01;
int_num=temperature;
decimal_num=(temperature-(int)temperature)*10;

send_command(0x00);
send_command(0x44);
send_command(0xC7);
if (int_num<10) send_data(0x00+percent_sign);else send_data(DIGITS[int_num/10]+percent_sign);
send_command(0xCB);
send_data(DIGITS[int_num%10]);
send_command(0xCE);
send_data(DIGITS[decimal_num]+1);
send_command(0xCA);
send_data(0x08);
send_command(0x97);
LCD_VAR.current_right_parameter=2;
}



void LCD_Show_Battery_Level(unsigned char battery_level)
{
send_command(0xCF);
send_data(BATTERY_LEVELS[battery_level]);
send_command(0x97);
}


void LCD_Show_Current(float current)
{
unsigned int int_num, decimal_num;
float decimal_part;

current=current+0.01;
int_num=current;
decimal_num=(current-(int)current)*10;

send_command(0x00);
send_command(0x44);
send_command(0xC2);
if (int_num<10) send_data(0x00+LCD_VAR.SPARK_sign);else send_data(DIGITS[int_num/10]+LCD_VAR.SPARK_sign);
send_command(0xC3);
send_data(DIGITS[int_num%10]+1);
send_command(0xC6);
send_data(DIGITS[decimal_num]+1);
send_command(0x97);
LCD_VAR.current_left_parameter=2;
if (LCD_VAR.current_right_parameter==1) LCD_Show_Voltage(LCD_VAR.VOLTAGE);
if (LCD_VAR.current_right_parameter==2) LCD_Show_Temperature(LCD_VAR.TEMPERATURE);
if (LCD_VAR.current_right_parameter==0) {send_command(0xC7);send_data(0x00); send_command(0x97); }
}

void LCD_Show_Percent(unsigned char percent)
{
send_command(0x00);
send_command(0x44);
send_command(0xC2);
if (percent<100) send_data(0x00+LCD_VAR.SPARK_sign);else send_data(DIGITS[percent/100]+LCD_VAR.SPARK_sign);
send_command(0xC3);
if (percent<10) send_data(0x00);else send_data(DIGITS[(percent%100)/10]);
send_command(0xC6);
send_data(DIGITS[percent%10]);
send_command(0xC7);
send_command(0x97);
LCD_VAR.current_left_parameter=1;
if (LCD_VAR.current_right_parameter==1) LCD_Show_Voltage(LCD_VAR.VOLTAGE);
if (LCD_VAR.current_right_parameter==2) LCD_Show_Temperature(LCD_VAR.TEMPERATURE);
if (LCD_VAR.current_right_parameter==0) {send_command(0xC7);send_data(0x01); send_command(0x97); }

}


void LCD_Show_Spark(unsigned char dummy)
{
LCD_VAR.SPARK_sign=1;
if (LCD_VAR.current_left_parameter==1) LCD_Show_Percent(LCD_VAR.PERCENT);
if (LCD_VAR.current_left_parameter==2) LCD_Show_Current(LCD_VAR.CURRENT);
if (LCD_VAR.current_left_parameter==0) {send_command(0xC2);send_data(0x01); send_command(0x97); }
}

void LCD_Hide_Spark(unsigned char dummy)
{
LCD_VAR.SPARK_sign=0;
if (LCD_VAR.current_left_parameter==1) LCD_Show_Percent(LCD_VAR.PERCENT);
if (LCD_VAR.current_left_parameter==2) LCD_Show_Current(LCD_VAR.CURRENT);
if (LCD_VAR.current_left_parameter==0) {send_command(0xC2);send_data(0x01); send_command(0x97); }
}




main()
{


CLK_DeInit();

CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);
CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1); // set 16 MHz for CPU





GPIO_DeInit(LED_PORT);
GPIO_Init(LED_PORT, LED, GPIO_MODE_OUT_PP_LOW_FAST);


GPIO_DeInit(BACKLIGHT_PORT);
GPIO_Init(BACKLIGHT_PORT, BACKLIGHT, GPIO_MODE_OUT_PP_LOW_FAST);
GPIO_WriteHigh(BACKLIGHT_PORT, BACKLIGHT);

GPIO_DeInit(IO_PORT);
GPIO_Init(IO_PORT, STB|SCLK|DIO|TM1722_POWER, GPIO_MODE_OUT_PP_LOW_FAST);
GPIO_WriteHigh(BACKLIGHT_PORT, BACKLIGHT);

GPIO_WriteHigh(IO_PORT, TM1722_POWER);

TIM1_DeInit();
TIM1_TimeBaseInit(32 - 1, TIM1_COUNTERMODE_UP, 1250 - 1, 0);
TIM1_SelectOutputTrigger(TIM1_TRGOSOURCE_UPDATE);

// ------------ ADC1 -------------------
GPIO_Init(GPIOD,GPIO_PIN_3,GPIO_MODE_IN_FL_NO_IT);

//
ADC1_DeInit();
ADC1_ScanModeCmd(ENABLE);
ADC1_DataBufferCmd(ENABLE);
ADC1_ITConfig(ADC1_IT_EOCIE, ENABLE);
ADC1_ClearITPendingBit(ADC1_IT_EOC);
ADC1_Init(ADC1_CONVERSIONMODE_SINGLE, ADC1_CHANNEL_1,
ADC1_PRESSEL_FCPU_D18, ADC1_EXTTRIG_TIM, ENABLE, ADC1_ALIGN_RIGHT,
ADC1_SCHMITTTRIG_CHANNEL0 | ADC1_SCHMITTTRIG_CHANNEL1, DISABLE);

// разрешаем прерывания
enableInterrupts();

// разрешаем работу таймера
TIM1_Cmd(ENABLE);
LCD_Clear(0);

while(1)
{

ADC1_StartConversion();
delay(60000);
LCD_Show_Voltage(11);
delay(60000);
}


LCD_Clear(0);

LCD_VAR.BATTERY_LEVEL=5;
LCD_VAR.CURRENT=18.2;
LCD_VAR.PERCENT=78;
LCD_VAR.VOLTAGE=13.5;
LCD_VAR.TEMPERATURE=25.6;


LCD_Show_Current(30.4);
LCD_Show_Voltage(LCD_VAR.VOLTAGE);
delay(600000);
LCD_Show_Percent(LCD_VAR.PERCENT);
delay(600000);
LCD_Show_Temperature(LCD_VAR.TEMPERATURE);
delay(600000);
LCD_Show_Percent(LCD_VAR.PERCENT+11);
delay(600000);
LCD_Show_Current(LCD_VAR.CURRENT);
delay(600000);
LCD_Show_Voltage(LCD_VAR.VOLTAGE);
delay(600000);
LCD_Show_Spark(0);
delay(600000);
LCD_Hide_Spark(0);
delay(600000);
LCD_Show_Percent(LCD_VAR.PERCENT);
delay(600000);
LCD_Show_Spark(0);
delay(600000);
LCD_Hide_Spark(0);
LCD_Show_Battery_Level(6);


while(1)
{


}

}


#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line){
while (1);
}
#endif


Решил через RTFM )))

Цитата
Open the project via ST Visual Develop. Right click on the project in workspace panel. Click "Settings". Click "C Compiler" tab. Choose "Optimizations" from the "Category" combobox. Select "Customize" from the "Optimizations" combobox. Make sure "Split Functions in Separate Sections" checkbox checked. And you're done.


Сообщение отредактировал zheka - Aug 12 2018, 06:41
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 12 2018, 08:08
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(zheka @ Aug 12 2018, 10:31) *
А программка то у меня небольшая, вряд ли, чтоб я успел вылезти за пределы памяти.

Надо не гадать, а заглянуть в map-файл.

PS: А вообще - с таким уменьем программирования, как в "программке", на STM8 делать нечего. Разве что хелло ворд под виндой писать... crying.gif
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- zheka   ST Visual Develop для STM8 и математические функции   Aug 11 2018, 08:59
- - iiv   замените на Код decimal_num=((int)...   Aug 11 2018, 10:00
- - zheka   Что-то не совсем понял идею... У меня, пока вы п...   Aug 11 2018, 11:11
|- - iiv   Цитата(zheka @ Aug 11 2018, 16:11) Въехал...   Aug 11 2018, 12:00
- - HardEgor   Цитата(zheka @ Aug 11 2018, 15:59) Если н...   Aug 11 2018, 12:19
- - Genadi Zawidowski   Example /* MODF.C */ #include <math.h> #in...   Aug 11 2018, 12:46
- - zheka   КодЧую, что это обработка датчика температуры... Н...   Aug 11 2018, 19:12
|- - jcxz   Цитата(zheka @ Aug 11 2018, 22:12) Нет, э...   Aug 11 2018, 19:15
- - Harbinger   Цитата(zheka @ Aug 11 2018, 22:12) Неуже ...   Aug 12 2018, 05:01
- - zheka   Цитатас таким уменьем программирования, как в ...   Aug 12 2018, 09:46
|- - jcxz   Цитата(zheka @ Aug 12 2018, 12:46) Или вы...   Aug 12 2018, 14:27
- - Harbinger   Аппаратный SPI там никак не задействовать? Кривая ...   Aug 12 2018, 11:53
|- - zheka   Цитата(Harbinger @ Aug 12 2018, 14:53) Ап...   Aug 12 2018, 12:45
|- - aaarrr   Цитата(zheka @ Aug 12 2018, 15:45) Как ок...   Aug 12 2018, 12:51
|- - zheka   Цитата(aaarrr @ Aug 12 2018, 15:51) Так в...   Aug 12 2018, 13:00
- - zheka   ЦитатаЗачем хотя-бы дублировать одни и те же опера...   Aug 12 2018, 14:33
|- - jcxz   Цитата(zheka @ Aug 12 2018, 17:33) Это гд...   Aug 12 2018, 14:53
- - zheka   ЦитатаПосмотрите на свои LCD_Show_Voltage()/LCD_Sh...   Aug 12 2018, 18:18
|- - jcxz   Цитата(zheka @ Aug 12 2018, 21:18) А ну-к...   Aug 12 2018, 19:18
|- - zheka   Цитата(jcxz @ Aug 12 2018, 22:18) Самое п...   Aug 12 2018, 19:44
|- - jcxz   Цитата(zheka @ Aug 12 2018, 22:44) Из ком...   Aug 13 2018, 14:05
- - Harbinger   Не видя всего проекта, сложно что-то сказать. Рабо...   Aug 13 2018, 17:02
- - zheka   Бесплатнее некуда ЦитатаThe evaluation license is ...   Aug 13 2018, 17:47
- - Harbinger   Второе и предлагалось. Cosmic на новом компе так и...   Aug 13 2018, 18:29
- - zheka   Н-да.. вы были правы. В IAR все работает. Продолж...   Aug 13 2018, 19:14
|- - jcxz   Цитата(zheka @ Aug 13 2018, 22:14) Почему...   Aug 13 2018, 20:30
- - zheka   Скачал полное руководство - RM0016 Описание halt з...   Aug 14 2018, 18:21
- - zheka   В общем я взял обычную китайскую отладочную плату,...   Aug 18 2018, 18:54
|- - jcxz   Цитата(zheka @ Aug 18 2018, 21:54) Возвра...   Aug 18 2018, 19:26
- - zheka   ЦитатаА почему Вы вообще именно на STM8S экономию ...   Aug 18 2018, 19:42
|- - jcxz   Цитата(zheka @ Aug 18 2018, 22:42) Я на В...   Aug 18 2018, 20:10
- - zheka   Проблема решена. Всем спасибо.   Aug 19 2018, 06:47


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st August 2025 - 10:58
Рейтинг@Mail.ru


Страница сгенерированна за 0.01399 секунд с 7
ELECTRONIX ©2004-2016