|
|
|
|
Скомпилировал как обычно программу в cvavr 1.25.9, запустил в симуляторе (vmlab) и, ... последний завалил меня сообщениями о нарушении регистра SREG (бит Z: Zero Flag); также симулятор отметил строки с нарушениями, это оказались операции логического сравнения, например: if(j==72) {j=0;} и т.п. и программа запускалась "через раз". Ещё оказалось, что значение переменной, например, j в момент выполнения логической операции почему-то неизвестно и после, SREG - становится испорченным. В программе переменные инициализированы у меня, как обычно делаю, при их объявлении, но получалось, что инициализации при компиляции не происходило. Всё пришло в норму, когда инициализировал переменные в функции main. Так и не понял, почему так стало, ведь переменные же обычно удобнее инициализировать сразу при их объявлении? |
|
|
Компилятор может оптимизировать в том числе и выделение памяти под переменные. Т.е. до момента использования память под них может быть и не выделена, соответственно они не проинициализированны. |
|
|
Digital: Всё пришло в норму, когда инициализировал переменные в функции main. Ну и правильно. А у вас как было? ...вы говорите про глобальные переменные или локальные? Если про глобальные, то компилятор под них отводит либо регистры, либо область ОЗУ. В свойствах проекта надо поиграться флажками. |
|
|
Про глобальные. В общем если галочку "Automatic register allocation" снять (случайно например ), то так получается. Но и с установленной, если переменных много, то SREG нет-нет, да испортится ( в симуляторе по крайней мере). Получается что в main (а не сразу при объявлении) инициализировать глобальные переменные вернее, тогда симулятор не ругается вообще (на одной и той же программе пробовал). Наверное такая особенность cvavr, буду знать теперь . |
|
|
Digital: Получается что в main (а не сразу при объявлении) инициализировать глобальные переменные вернее Честно говоря, непонятное утверждение.  Зачем вобще их инициализировать? Ведь для чего нужны глобальные переменные? Чтобы передавать какие-то значения из одной функции в другую, пользуясь переменной, как средством передачи. Находясь в любой точке программы вы можете положить туда число, которое всегда можно считать из другой любой точки программы. Именно для этого они и нужны. Хотя в большинстве случаев можно обойтись и без них. Для этого ваши функции должны быть не "void Функция (void)", а уметь принимать и возвращать численные значения, например "char функция (char x)". В каждой функции объявляется своя собственная переменная (локальная), которая работает только внутри этой функции. Конечно могут быть и исключения. Например прерывания. Функцию прерывания вы не вызываете из программы. Прерывания возникают под влиянием каких-то других, независимых от программы факторов. Вот тут-то и могут пригодиться глобальные переменные опять же для того, чтобы воспользоваться в обработчике прерывания каким-то числом, сформированным в других функциях. //***************************************************************** Теперь ваш случай. Присваивать глобальной переменной какое-то значение до объявления главной функции вообще бессмысленно, т. к. переменная это всего навсего "вагон". Заполнять этот вагон углем или песком или еще чем-нибудь мы будем решать по ходу программы и по мере необходимости. Другими словами, глобальные переменные не нуждаются в начальной инициализации! Если же вы хотите проинициализировать переменную и не менять ее по ходу программы вообще, то это уже будет не переменная, а константа. Константы действительно объявляются и им присваивается значение вне главной или каких-либо других функций. В контроллерах константы заносятся во флеш-память. Чтобы компилятор отличил константу от переменной надо писать например так: flash unsigned char x = 0x12; |
|
|
Zandy: Зачем вобще их инициализировать? Ну вроде как по умолчанию, если не указать явно они будут равны нулю, но этого не происходило, я так понял из-за отключенной в cvavr "Automatic register allocation". Zandy: Вот тут-то и могут пригодиться глобальные переменные опять же для того, чтобы воспользоваться в обработчике прерывания каким-то числом, сформированным в других функциях. Есть такое В обработчике выбирается то или иное значение полученное из while(1) - основного цикла программы. Zandy: Если же вы хотите проинициализировать переменную и не менять ее по ходу программы вообще, то это уже будет не переменная, а константа. Такое тоже имеется, но сделал как bit, т.к. значение или 0 или 1. |
|
|
Мне вот что не понятно. Когда есть нарушение SREG, то cvavr размещает переменные по каким-то адресам или смещениям, непонятно где в общем? См. 1.jpg (34kb). А когда всё нормально, то вот так, с явным указанием регистров (2.jpg 36.5kb). 
|
|
|
2.jpg 
|
|
|
Digital: Такое тоже имеется, но сделал как bit, т.к. значение или 0 или 1. Тут имел ввиду, что 0 или 1 прописываются один раз, в зависимости от того, нужен прямой или инверсный сигнал на выходе. |
|
|
А вы знаете, что битовые переменные (записанные, например, как bit х ) доступны только в главной функции? Ни в каких других функциях их использовать нельзя. |
|
|
|
|