Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.07.2011, 11:49   #11
nibir
Пользователь
 
Регистрация: 05.07.2011
Сообщений: 11
По умолчанию

Полный текст большеват, но все же выложу:
Код:
#include "main_task.h"
#include "control_task.h"
#include "touch_task.h"
#include "lcd_beep_task.h"
#include "acp_task.h"
#include <avr/eeprom.h>
#include <string.h>
#include <stdlib.h>
#include <avr/pgmspace.h>
#include <util/delay.h>

#define CLOCK_UPDATE 300  //Экран обновляется 

const char msgwelcome[] PROGMEM = "Hello        "; //под 16 символьный
//const char msgready[] PROGMEM = "Ready!          "; //под 16 символьный
//const char msgwelcome[] PROGMEM = "   LCD Hello                    "; //под 32 символьный
const char msgok[] PROGMEM = "V=";


void control_task_init(void ) //инициализация контролов 
{

}

void control_task(void )
{
	//CAP
	static uint8_t inp[2]={0x00,0x00};
	static uint8_t outp[2];
	
	//ACPA
	static uint8_t inp2[2]={0x00,0x00};
	static uint8_t outp2[2];
	static long voltage;
	static long default_voltage = 15180; //выдает трансформатор тока, это с множителем х10 000  
	static long amperage;
	
	//ACPV
	static uint8_t inp3[2]={0x00,0x00};
	static uint8_t outp3[2];
	static uint16_t voltage_sr;
	static uint16_t voltage_ch;
	static int		ii;
	
	
	//init string
	strncpy_P(lcdstring, msgwelcome, strlen_P(msgwelcome)); //Приветствие пишем тут. 
	setLcdUpdate();
	MOS_startTimer( TIMER_UPDATE, 1000);
	MOS_WaitTimeout( TIMER_UPDATE);
	//--------------------------
	//strncpy_P(lcdstring, msgready, strlen_P(msgready));
	//setLcdUpdate();
	//MOS_startTimer( TIMER_UPDATE, 3000);
	//MOS_WaitTimeout( TIMER_UPDATE);
	
	
	//-------------------------
	initLcdEnv();
	//LcdState_P( msgok, strlen_P( msgok));
	//setLcdValue( touch_encounter, 0, 1); //Начальные значения ставим тут

	MOS_startTimer( TIMER_UPDATE, CLOCK_UPDATE);
	for(;;)
	{
		
		//MOS_Scheduler();
		MOS_WaitCheckAndwithTimeout(touch_flag, 0xff, TIMER_UPDATE); 
		if( MOS_isWaitTimeout())
		{
			
			/*
			//----------------------CAP----------------------------------------
			PORTB &=  ~_BV(PB1);
			SPI_MasterTrRc(inp, outp, CAP);
			//-----------------------------------------------------------------
			
			
			
			//-------------------------------------ACPA------------------------
			SPI_MasterTrRc(inp2, outp2, ACPA);
			voltage = ((unsigned long)((((uint16_t)outp2[0])<<8)+outp2[1]))*110/18; //напряжение в вольтах с трансформатора тока 1.51 по умолчанию  (11/18  ) получаем с множителем х10 000
			amperage = ((voltage - default_voltage)/25); //на 25 мв приходится одна ампера! 
			if (amperage < 0 ) //default может быть не очень точным и в результате уходить ниже нуля может. 
			{
				amperage = 0;			
			}
			setLcdValue((amperage), 1, 0); //вывод амперов
			
			//------------------------------------------------------------------
			*/
			
			
			//----------------------ACPV-----------------------------------------
			ii=1;
			voltage_sr = 0;
			
			
			
			while (ii<=1)
			{
				SPI_MasterTrRc(inp3, outp3, ACPV);
				voltage_sr += ((((uint16_t)outp3[0])<<8)+outp3[1])*13/213; // 2.5/4096*100 делитель на 100 стоит на входе
				++ii;
			}
			
			
			
						
			setLcdValue(voltage_sr, 0, 1); //Вывод вольтов 
			//-------------------------------------------------------------------
			
			
			
			
			
			//setLcdValue( utsecs, 0, 0);              //С написанием этих функций появляются счетчики в окружении. 
			//setLcdValue( fpscount/1000, 0, 2);		//Вывод измерений
			MOS_startTimer( TIMER_UPDATE, CLOCK_UPDATE);
		}
		if(isTouchPower())
		{
			clrTouchPower();
			//LcdBeepEngine(1, 1);
		}
		if(isTouchLPower())
		{
			clrTouchLPower();
			//LcdBeepEngine(1, 10);
		}
//checkbtn:
		if(isTouchEncbut())
		{
			clrTouchEncbut();
			//LcdBeepEngine(1, 10);
		}
		if(isTouchLEncbut())
		{
			clrTouchLEncbut();
			//LcdBeepEngine(1, 10);
		}
		if(isTouchEncoder())
		{
			clrTouchEncoder();
			if (touch_encounter >= 0)
			{	
				inp[0]=(0x05)*touch_encounter;
				inp[1]=(0x05)*touch_encounter;
				
				//setLcdValue( touch_encounter, 0, 1); // (int, знаков после запятой, место (012))
			}
			else
			{
				touch_encounter = 0;
			}				
						
			//LcdBeepEngine(1, 1);
		}
	}
}
nibir вне форума Ответить с цитированием
Старый 06.07.2011, 11:51   #12
nibir
Пользователь
 
Регистрация: 05.07.2011
Сообщений: 11
По умолчанию

Ну и работа с spi
Код:
#include "main_task.h"
#include "control_task.h"
#include "touch_task.h"
#include "lcd_beep_task.h"
#include "acp_task.h"
#include <avr/eeprom.h>
#include <string.h>
#include <stdlib.h>
#include <avr/pgmspace.h>
#include <util/delay.h>

/*
Должна уметь принимать значения:
ACPV  0 (CPOL 1 CPHA 1) 2 байта 
ACPA  1 (CPOL 1 CPHA 1) 2 байта
CAP   2 (CPOL 0 CPHA 1) 3 байта 1 00

Будет вызываться при передаче данных, каждый раз 

*/

void ChipSelectEdit (int dev, int up_or_down)
{
		if (up_or_down)
		{
			if (dev == ACPA)
				PORTB |=  _BV(PB2);
			if (dev == ACPV)
				PORTB |=  _BV(PB3);
			if (dev == CAP)
				PORTB |=  _BV(PB4);			
		}
		if (!up_or_down)
		{
			if (dev == ACPA)
				PORTB &=  ~_BV(PB2);
			if (dev == ACPV)
				PORTB &=  ~_BV(PB3);
			if (dev == CAP)
				PORTB &=  ~_BV(PB4);			
		}
}

void SPI_MasterInit()
{
	SPCR &= ~(1<<CPOL); //по низходящему
	SPCR |= (1<<CPHA);
	DDRB |= (1<<PB5); //MOSI
	DDRB |= (1<<PB7); //CLK
	/* Enable SPI, Master, set clock rate fck/16 */
	SPCR |= ((1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0));//|(1<<CPHA)); //разрешили spi, как мастер, частота /16, 
	//SPCR &= ~(1<<DORD); //первый идет старший
}
/*


*/
void SPI_MasterTrRc(uint8_t *cDataIn, uint8_t *cDataOut, int dev)
{
	ChipSelectEdit (dev, DOWN);
	
	_delay_ms(1);
	
	if (dev == CAP)
	{
		SPDR = 0x00;
		while(!(SPSR & (1<<SPIF)));
	}
	
	//_delay_ms(1);
		
	SPDR = cDataIn[0];
	//SPDR = 0x00;
	while(!(SPSR & (1<<SPIF)));
	cDataOut[0] = SPDR;
	
	//_delay_ms(1);
	
	SPDR = cDataIn[1];
	//SPDR = 0x00;
	while(!(SPSR & (1<<SPIF))); //Ждем пока не завершится передача
	cDataOut[1] = SPDR;
	
	//_delay_ms(1);
	
	ChipSelectEdit (dev, UP);
}
Проект передали вот в таком плоховатом виде. Сижу разбираюсь
nibir вне форума Ответить с цитированием
Старый 06.07.2011, 12:45   #13
nibir
Пользователь
 
Регистрация: 05.07.2011
Сообщений: 11
По умолчанию

Это невероятно. Пойду ка я куплю себе бубен и буду плясать вокруг установки с ним. Переписал функцию так:
Код:
uint16_t SPI_MasterTrRc(uint8_t *DataIn, int dev)
{
	//uint16_t DataOut;
	uint16_t DataOutUpByte;
	uint8_t DataOutDownByte;
	
	
	ChipSelectEdit (dev, DOWN);
	
	_delay_ms(1);
	
	if (dev == CAP)
	{
		SPDR = 0x00;
		while(!(SPSR & (1<<SPIF)));
	}
	
	//_delay_ms(1);
		
	SPDR = DataIn[0];
	
	//SPDR = 0x00;
	while(!(SPSR & (1<<SPIF)));
	DataOutUpByte = SPDR;
	
	//_delay_ms(1);
	
	SPDR = DataIn[1];
	//SPDR = 0x00;
	while(!(SPSR & (1<<SPIF))); //Ждем пока не завершится передача
	DataOutDownByte = SPDR;
	
	//_delay_ms(1);
	
	ChipSelectEdit (dev, UP);
	
	return ((DataOutUpByte<<8) + DataOutDownByte);
}
Все прекрасно заработало. Но я не уверен в чем отличия то? Объясните момент такой. Когда аллоцируется память под то что возвращает функция?
Установка будет работать с большими напряжениями и токами, будут обрабатываться материалы в ядовитой среде, посему не хотелось бы никаких "плясок с бубном" в программе, чтоб она неожиданно не заглючила.
nibir вне форума Ответить с цитированием
Старый 06.07.2011, 13:01   #14
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

Код:
while(!(SPSR & (1<<SPIF)));
Я так понимаю, что значения этих переменых меняются в другом потоке.
Или я чего то не разглядел.
Тогда чем обеспечена синхронизация между двумя потоками? Не вижу.
Чтение и запись в эти SPSR, SPIF надо бы обрамить критической секцией.
Иначе, конечно, возможно непредсказуемое поведение.
EUGY вне форума Ответить с цитированием
Старый 06.07.2011, 13:24   #15
nibir
Пользователь
 
Регистрация: 05.07.2011
Сообщений: 11
По умолчанию

Цитата:
Сообщение от EUGY Посмотреть сообщение
Код:
while(!(SPSR & (1<<SPIF)));
Я так понимаю, что значения этих переменых меняются в другом потоке.
Или я чего то не разглядел.
Тогда чем обеспечена синхронизация между двумя потоками? Не вижу.
Чтение и запись в эти SPSR, SPIF надо бы обрамить критической секцией.
Иначе, конечно, возможно непредсказуемое поведение.
Это ничего особенного. Всего лишь ожидание флагов о том что передача байта через spi закончилась.
Это не переменные а дефайны.
Код:
#define SPSR _SFR_IO8(0x0E)
#define SPIF 7
В AVR программировании по-моему половина кода - системные дефайны.
В программе нет многопоточности как таковой.
nibir вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Передача в функцию указателя на динамический массив Airou Общие вопросы C/C++ 4 05.05.2011 17:07
Указатель на массив указателей на массив char'ов... SrgGld Общие вопросы C/C++ 0 19.11.2010 23:35
скорость работы указателей на функцию coinkrsk Общие вопросы C/C++ 3 31.10.2010 21:13
Передача списка указателей (TList) как параметр в dll sneksnek2006 Общие вопросы C/C++ 1 28.10.2010 11:33
Передача указателя на массив в функцию loser Общие вопросы C/C++ 2 19.02.2010 19:41