Я использую 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.