Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » attiny13 уменьшение размера программы.


attiny13 уменьшение размера программы.

Сообщений 1 страница 29 из 29

1

Здравствуйте! Осваиваю баском. Появились вопросы
Есть такое устройство:
Ссылка
но она на меге8, что мне не подходит. Хочу попробовать засунуть код в тиньку13, но программа ругается на нехватку памяти и некоторые моменты.
исходный код:

Код:
'For BASCOM AVR v.207x

$regfile = "m8def.dat"
$crystal = 8000000
$hwstack = 40
$swstack = 16
$framesize = 32

Dim W As Byte , W1 As Byte , W2 As Byte , Wxx As Byte , Uxx As Byte , Uon As Byte , Uoff As Byte
Dim I As Word
Dim Calc1 As Single , Calc2 As Single

Config Portd.0 = Input
Butt Alias Pind.0

Config Adc = Free , Prescaler = Auto , Reference = Internal
Sfior = &B0001000

Config Timer2 = Pwm , Compare Pwm = Clear Up , Prescale = 32



100:

Pwm2 = 0
Readeeprom Wxx , 0
Readeeprom Uon , 1
Readeeprom Uoff , 2



W1 = 0                                                      '25
For W = 0 To Wxx
Pwm2 = W
W1 = W1 + 4
Waitms W1
Next
Waitms 800


110:

If Butt = 0 Then
   Wait 1
   If Butt = 0 Then Goto Nastr
End If


Calc1 = 0
For I = 0 To 100
   Gosub Adc1
   Calc1 = Calc1 + W
Next
Calc1 = Calc1 / 100
W1 = Int(calc1)

If W1 > Uon Then Goto Pusk

Goto 110




Pusk:

Pwm2 = 255
Waitms 300


200:

If Butt = 0 Then
   Wait 1
   If Butt = 0 Then Goto Nastr
End If

Calc1 = 0
For I = 0 To 100
   Gosub Adc1
   Calc1 = Calc1 + W
Next
Calc1 = Calc1 / 100
W1 = Int(calc1)


If W1 < Uoff Then
   Pwm2 = Wxx
   Goto 110
Else
   Goto 200
End If



Nastr:

Gosub Adc3
Wxx = W
Pwm2 = Wxx
If Butt = 0 Then Goto Nastr
Waitms 800
Writeeeprom Wxx , 0


Calc1 = 0
For I = 0 To 100
   Gosub Adc1
   Calc1 = Calc1 + W
Next
Calc1 = Calc1 / 100
Calc1 = Calc1 * 1.17
Uon = Int(calc1)
Writeeeprom Uon , 1


For W = Wxx To 255
   Pwm2 = W
   Waitms 20
Next
Waitms 600

Calc1 = 0
For I = 0 To 100
   Gosub Adc1
   Calc1 = Calc1 + W
Next
Calc1 = Calc1 / 100
Calc1 = Calc1 * 1.1
Uoff = Int(calc1)

Writeeeprom Uoff , 2

Pwm2 = 0
Waitms 500
Goto 100





Adc1:

Admux = &B1110001
Bitwait Adcsr.4 , Set
W = Adch
Return


Adc3:

Admux = &B1110011
Bitwait Adcsr.4 , Set
W = Adch
Return

Вот что я выдумал:

Код:
'For BASCOM AVR v.207x

$regfile = "attiny13.dat"
$crystal = 9600000
$hwstack = 0
$swstack = 0
$framesize = 0
$sim
Dim W As Byte , W1 As Byte , W2 As Byte , Wxx As Byte , Uxx As Byte , Uon As Byte , Uoff As Byte
Dim I As Word
Dim Calc1 As Single , Calc2 As Single

Config Portb.3 = Input
Butt Alias Pinb.3


Config Adc = Free , Prescaler = Auto , Reference = Internal
Config Portb.0 = Output                                     'Sfior = &B0001000

Config Timer0 = Pwm , Compare A Pwm = Clear Up , Prescale = 8



100:

Pwm0a = 0
Readeeprom Wxx , 0
Readeeprom Uon , 1
Readeeprom Uoff , 2



W1 = 0                                                      '25
For W = 0 To Wxx
Pwm0a = W
W1 = W1 + 4
Waitms W1
Next
Waitms 800


110:

If Butt = 0 Then
   Wait 1
   If Butt = 0 Then Goto Nastr
End If


Calc1 = 0
For I = 0 To 100
   Gosub Adc1
   Calc1 = Calc1 + W
Next
Calc1 = Calc1 / 100
W1 = Int(calc1)

If W1 > Uon Then Goto Pusk

Goto 110




Pusk:

Pwm0a = 255
Waitms 300


200:

If Butt = 0 Then
   Wait 1
   If Butt = 0 Then Goto Nastr
End If

Calc1 = 0
For I = 0 To 100
   Gosub Adc1
   Calc1 = Calc1 + W
Next
Calc1 = Calc1 / 100
W1 = Int(calc1)


If W1 < Uoff Then
   Pwm0a = Wxx
   Goto 110
Else
   Goto 200
End If



Nastr:

Gosub Adc3
Wxx = W
Pwm0a = Wxx
If Butt = 0 Then Goto Nastr
Waitms 800
Writeeeprom Wxx , 0


Calc1 = 0
For I = 0 To 100
   Gosub Adc1
   Calc1 = Calc1 + W
Next
Calc1 = Calc1 / 100
Calc1 = Calc1 * 1.17
Uon = Int(calc1)
Writeeeprom Uon , 1


For W = Wxx To 255
   Pwm0a = W
   Waitms 20
Next
Waitms 600

Calc1 = 0
For I = 0 To 100
   Gosub Adc1
   Calc1 = Calc1 + W
Next
Calc1 = Calc1 / 100
Calc1 = Calc1 * 1.1
Uoff = Int(calc1)

Writeeeprom Uoff , 2

Pwm0a = 0
Waitms 500
Goto 100


Adc1:

'Admux = &B1110001
Bitwait Adcsr.4 , Set
'W = Adch
W = Getadc(1)
Return


Adc3:

'Admux = &B1110011
Bitwait Adcsr.4 , Set
'W = Adch
W = Getadc(2)
Return


ругается на Sfior = &B0001000. Что это такое? может кто нибудь из гуру мне разъяснить? В даташите на мегу8 фигурирует как спец-функция для портов. Но в даташите на тиньку13 ее нет. С PWM в тиньке немного разобрался.
Admux = &B1110011 ??? конкретно про команду прочитал в разделе хелп на сайте баскома, но как задать адрес adc2 так и не разобрался...
Уважаемые гуру направьте меня, если возможно помогите оптимизировать код! Если это не возможно, буду другой мк пробовать, в наличии еще есть тинька24... но она мне тоже как бы не подходит, плата слишком маленькая...

0

2

Как вариант, написать на асме. Может и влезет.

0

3

NewUserBascom Sfior = &B0001000 поднимаем бит в регистре, разрешаем выбор канала АЦП. Admux = &B1110011 последние два бита - выбор канала АЦП (1 или 3) для измерения. В режимах работы и настройки.

0

4

Спасибо за помощь! капаю дальше! курю хелп с сайта баском.
еще вопрос: в tiny13 есть внутренний ион, если даташит не врет то он на 1,1в. Возможно ли это напряжение разделить на N(чтоб получить ~0,3в) и отправить это напряжение на один из входов компаратора?
решил упростить программу: убрать все, логика работы такая: снимаю сигнал pwm, если напруга на компараторе не превышает 0,3в, то pwm=10%, если превысило то pwm=100%.

Отредактировано NewUserBascom (2017-06-22 10:47:22)

0

5

нет. только использовать внешний ИОН или делитель напряжения и использовать ногу AIN1 (отрицательный вход компаратора) непосредственно.

0

6

код в студию, что получилось или пытаешься сделать.

0

7

MACTEPok написал(а):

нет. только использовать внешний ИОН или делитель напряжения и использовать ногу AIN1 (отрицательный вход компаратора) непосредственно.


в этом вся и загвоздка... ноги компаратора это и ноги pwm выхода...
Сейчас смотрел подобную конструкцию на 13 тиньке, только код на с. очень длинный и влез... тогда я ничего не понимаю...

0

8

MACTEPok написал(а):

код в студию, что получилось или пытаешься сделать.

код выше... я все же хочу сделать прогу попроще, но с сохранением функционала

0

9

NewUserBascom написал(а):

только код на с. очень длинный и влез

Там использовались вычисления с плавающей точкой?
Попробуйте такой вариант.

Код:
'For BASCOM AVR v.207x

$regfile = "attiny13.dat"
$crystal = 9600000
$hwstack = 10
$swstack = 0
$framesize = 0

$sim
Dim W As Byte , W1 As Byte , W2 As Byte , Wxx As Byte , Uxx As Byte , Uon As Byte , Uoff As Byte
Dim I As Word
Dim Calc1 As Long                                 ', Calc2 As Long

Config Portb.3 = Input
Butt Alias Pinb.3


Config Adc = Free , Prescaler = Auto , Reference = Internal
Config Portb.0 = Output                                     'Sfior = &B0001000

Config Timer0 = Pwm , Compare A Pwm = Clear Up , Prescale = 8



100:

Pwm0a = 0
Readeeprom Wxx , 0
Readeeprom Uon , 1
Readeeprom Uoff , 2



W1 = 0                                                      '25
For W = 0 To Wxx
Pwm0a = W
W1 = W1 + 4
Waitms W1
Next
Waitms 800


110:

If Butt = 0 Then
   Wait 1
   If Butt = 0 Then Goto Nastr
End If


Calc1 = 0
For I = 0 To 64                                   ' 100
   Gosub Adc1
   Calc1 = Calc1 + W
Next
'Calc1 = Calc1 / 100
Shift Calc1 , Right , 6
W1 = Low(calc1)

If W1 > Uon Then Goto Pusk

Goto 110




Pusk:

Pwm0a = 255
Waitms 300


200:

If Butt = 0 Then
   Wait 1
   If Butt = 0 Then Goto Nastr
End If

Calc1 = 0
For I = 0 To 64                                   '100
   Gosub Adc1
   Calc1 = Calc1 + W
Next
'Calc1 = Calc1 / 100
Shift Calc1 , Right , 6
W1 = Low(calc1)


If W1 < Uoff Then
   Pwm0a = Wxx
   Goto 110
Else
   Goto 200
End If



Nastr:

Gosub Adc3
Wxx = W
Pwm0a = Wxx
If Butt = 0 Then Goto Nastr
Waitms 800
Writeeeprom Wxx , 0


Calc1 = 0
For I = 0 To 64                                   '100
   Gosub Adc1
   Calc1 = Calc1 + W
Next
'Calc1 = Calc1 / 100
'Calc1 = Calc1 * 1.17
Shift Calc1 , Right , 6
Uon = Low(calc1)
Writeeeprom Uon , 1


For W = Wxx To 255
   Pwm0a = W
   Waitms 20
Next
Waitms 600

Calc1 = 0
For I = 0 To 64                                   '100
   Gosub Adc1
   Calc1 = Calc1 + W
Next
'Calc1 = Calc1 / 100
'Calc1 = Calc1 * 1.1
Shift Calc1 , Right , 6
Uoff = Low(calc1)

Writeeeprom Uoff , 2

Pwm0a = 0
Waitms 500
Goto 100


Adc1:

'Admux = &B1110001
Bitwait Adcsr.4 , Set
'W = Adch
W = Getadc(1)
Return


Adc3:

'Admux = &B1110011
Bitwait Adcsr.4 , Set
'W = Adch
W = Getadc(2)
Return

0

10

Пётр написал(а):

Там использовались вычисления с плавающей точкой?

Простите,  я только начал изучать все месяц назад... по этому для меня еще такие понятия как "вычисление с плавающей точкой" пока ругательства...

Попробовал. не симулирует, но хотя бы компилирует, память заполнена на 101%. Изучаю ваш код.

Отредактировано NewUserBascom (2017-06-22 17:17:00)

0

11

Это не целочисленные вычисления, т. е. дробные.

0

12

Пётр написал(а):

Это не целочисленные вычисления, т. е. дробные.

А возможно ли привести эту программу к целым вычислениям? я так понимаю будет работать более грубо...

0

13

Выше в сообщении разместил код. По размеру он помещается в МК.

0

14

Пётр написал(а):

Выше в сообщении разместил код. По размеру он помещается в МК.

Я только что его поместил в баском. в свойствах написано что занято 101%

Код:
'For BASCOM AVR v.207x

$regfile = "attiny13a.dat"
$Crystal=9600000
$hwstack = 10
$swstack = 0
$framesize = 0


Dim W As Byte , W1 As Byte , W2 As Byte , Wxx As Byte , Uxx As Byte , Uon As Byte , Uoff As Byte
Dim I As Word
Dim Calc1 As Long

Config Portb.3 = Input
Butt Alias Pinb.3
Config Portb.0 = Output

Config Adc = Free , Prescaler = Auto , Reference = Internal
Config Timer0 = Pwm , Compare A Pwm = Clear Up , Prescale = 64

100:

Wxx = 60

Pwm0a = 0
Readeeprom Uon , 1
Readeeprom Uoff , 2



W1 = 0                                                      '25
For W = 0 To Wxx
Pwm0a = W
W1 = W1 + 4
Waitms W1
Next
Waitms 800


110:

If Butt = 0 Then
   Wait 1
   If Butt = 0 Then Goto Nastr
End If

Calc1 = 0
For I = 0 To 64
   Gosub Adc1
   Calc1 = Calc1 + W
Next
Shift Calc1 , Right , 6
W1 = Low(calc1)
If W1 > Uon Then Goto Pusk
Goto 110


Pusk:

Pwm0a = 255
Waitms 300

200:

If Butt = 0 Then
   Wait 1
   If Butt = 0 Then Goto Nastr
End If

Calc1 = 0
For I = 0 To 100
   Gosub Adc1
   Calc1 = Calc1 + W
Next
Shift Calc1 , Right , 6                                     'new
W1 = Low(calc1)
If W1 < Uoff Then
   Pwm0a = Wxx
   Goto 110
Else
   Goto 200
End If



Nastr:

Pwm0a = Wxx
If Butt = 0 Then Goto Nastr
Waitms 800

Calc1 = 0
For I = 0 To 64
   Gosub Adc1
   Calc1 = Calc1 + W
Next
Shift Calc1 , Right , 6
Uon = Low(calc1)
Writeeeprom Uon , 1


For W = Wxx To 255
   Pwm0a = W
   Waitms 20
Next
Waitms 600

Calc1 = 0
For I = 0 To 64
   Gosub Adc1
   Calc1 = Calc1 + W
Next
Shift Calc1 , Right , 6
Uoff = Low(calc1)
Writeeeprom Uoff , 2

Pwm0a = 0
Waitms 500
Goto 100


Adc1:

Admux = &B1110001
Bitwait Adcsr.4 , Set
W = Adch
Return


вот немного упращенная программа, без потенциометра. вроде влезает 96%.
что делать с этим:
$hwstack = 10
$swstack = 0
$framesize = 0

оставлять все по нулям?

0

15

Если ставлю цифры 10 20 30 ругается... что sram не хватает. пробовал разные, общим объемом до 64.. но ругается... думаете заработает?

0

16

Код влезает как есть. Занимает 95%. http://rgho.st/8vskK4fbw

NewUserBascom написал(а):

думаете заработает?

Попробуйте.

0

17

Я понимаю,с точки зрения спортивного интереса и проч.впихнуть код в тини13 под обрез-самое то.А если ,как у ТС,плата маленькая,можно просто взять ATtiny25/45/85.При таких же размерах как у тини13 ещё и на последующие хотелки останется.

0

18

Пётр написал(а):

Код влезает как есть. Занимает 95%. http://rgho.st/8vskK4fbw
NewUserBascom написал(а):

    думаете заработает?

Попробуйте.


Пётр, я открыл ваш архив, да bin файл у вас весит меньше килобайта, но когда я из вашего файла .bas перекомпелирую, то у меня bin файл размером больше килобайта...
что то у меня не так с программой... какая у вас версия? Я пока пользуюсь 2.0.7.5(demo), компилятор версии 2.0.7.5.003
Может какие настройки нужны?

Отредактировано NewUserBascom (2017-06-23 13:17:25)

0

19

Компилировал в BASCOM-AVR 2.0.8.0.
В настройках можно включить оптимизацию кода. Возможно размер прошивки уменьшится. Сейчас нет установленной версии 2.0.7.5 чтобы проверить.

0

20

Пётр написал(а):

Компилировал в BASCOM-AVR 2.0.8.0.
В настройках можно включить оптимизацию кода. Возможно размер прошивки уменьшится. Сейчас нет установленной версии 2.0.7.5 чтобы проверить.


Сделал. Обновился до 2.0.7.9, включил оптимизацию. теперь все ок.

0

21

А если в твоем коде  этот кусок

Код:
Calc1 = 0
For I = 0 To 64
   Gosub Adc1
   Calc1 = Calc1 + W
Next

вынести в отдельную подпрограмму:

Код:
.....
Gosub Rt1
.....

Rt1:
Calc1 = 0
For I = 0 To 64
   Gosub Adc1
   Calc1 = Calc1 + W
Next
Return


то размер кода сократится аж на 250 байт! и свободные байты можно использовать  для всяких рюшечек типа лампочки  :glasses:

Отредактировано Penumbra (2017-06-24 13:48:01)

0

22

Penumbra написал(а):

А если в твоем коде  этот кусок
Код:

Calc1 = 0
For I = 0 To 64
   Gosub Adc1
   Calc1 = Calc1 + W
Next

вынести в отдельную подпрограмму:
Код:

.....
Gosub Rt1
.....

Rt1:
Calc1 = 0
For I = 0 To 64
   Gosub Adc1
   Calc1 = Calc1 + W
Next
Return

то размер кода сократится аж на 250 байт! и свободные байты можно использовать  для всяких рюшечек типа лампочки  :glasses:

Отредактировано Penumbra (2017-06-24 11:48:01)

Спасибо за помощь! Экспериментирую...

0

23

Не заработал...

0

24

вопрос как раз по Тини-13. есть размер аппаратного стека, по умолчанию он 32. баском говорит, что если используем прерывания - то размер надо увеличивать. каждое прерывание использует 2 бита. если у меня ШИМ на таймере0 и кнопка на прерывании0 то это у нас что - 4 бита добавлять надо или куда? и как выбирать размер программного стека и размер фрейма?

0

25

IDok написал(а):

каждое прерывание использует 2 бита

Где такое написано?

IDok написал(а):

как выбирать размер программного стека и размер фрейма?

$hwstack - $swstack - $framesize - подскажите новичку.

0

26

IDok написал(а):

Где такое написано?

байта, байта разумеется. а пишет сие сам Баском в настройках МК

0

27

IDok написал(а):

пишет сие сам Баском в настройках МК

Про прерывания пишет?

0

28

Пётр
он пишет дословно: "значение по умолчанию 32. каждый вызов подпрограммы занимает 2 байта. если используете прерывания - увеличивайте значение"
с подпрограммой понятно - видим gosub - 2 байта пишем. а к подпрограммам прерываний это относится? если я за один цикл вызываю одну подпрограмму прерывания - это считается как 1 раз или как все?

0

29

IDok написал(а):

к подпрограммам прерываний это относится?

Кроме адреса возврата в стеке сохраняются регистры процессора. https://avrhelp.mcselec.com/on_interrupt.htm

0


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » attiny13 уменьшение размера программы.