Перейти к содержанию
    

Помогите с программой на Си - ATtiny261 и mcp41010

Здравствуйте! Не идёт программа для управления цифровым потенциометром mcp41010 от ATtiny261.

 

В компиляции ошибок нет но резистор не управляется и никак не реагирует.

Сопротивление mcp41010 должно менятся от минимального до максимального в цикле.

 

PORTA.6 соединён с CS

PORTA.5 соединён с SCK

PORTA.4 соединён с SI

 

Листинг программы на Си:

 

/*****************************************************
This program was produced by the
CodeWizardAVR V2.04.5a Evaluation
Automatic Program Generator
© Copyright 1998-2009 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project : 
Version : 
Date	: 20.06.2012
Author  : Freeware, for evaluation and non-commercial use only
Company : 
Comments: 


Chip type			   : ATtiny261
AVR Core Clock frequency: 4,000000 MHz
Memory model			: Tiny
External RAM size	   : 0
Data Stack size		 : 32
*****************************************************/

#include <tiny261.h>
#include <delay.h>

// Declare your global variables here

int i;

void CommandTheResistor (unsigned short R)
{

PORTA.5=1;
delay_us(70);
PORTA.6=0;
delay_us(30); 
PORTA.5=0;  //first clock
delay_us(100);
PORTA.5=1;
delay_us(100);
PORTA.5=0;	//second clock 
PORTA.4=0;
delay_us(100);
PORTA.5=1;
delay_us(30);
PORTA.4=1;
delay_us(70);
PORTA.5=0;	//third clock
delay_us(100);
PORTA.5=1;
delay_us(30);
PORTA.4=0;
delay_us(70);
PORTA.5=0;   //fourth clock
delay_us(100);
PORTA.5=1;
delay_us(100);
PORTA.5=0;	//fifth clock 
delay_us(100);
PORTA.5=1;
delay_us(100);
PORTA.5=0;	//sixth clock 
delay_us(100);
PORTA.5=1;
delay_us(30);
PORTA.4=1;
delay_us(70);
PORTA.5=0;	//seventh clock
delay_us(100);
PORTA.5=1;
delay_us(30);
PORTA.4=0;
delay_us(70);
PORTA.5=0;   //eighth clock
delay_us(100);

for(i = 0; i<=7; i++)
  {
  PORTA.5=1;
  delay_us(30);
  PORTA.4 = R%2;	   
  R=R/2;	 
  delay_us(70);
  PORTA.5=0;
  delay_us(100);
  }
PORTA.6 = 1; 
} 

void main(void)
{
// Declare your local variables here

unsigned short RESISTANCE;


// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=Out Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=0 State5=0 State4=0 State3=T State2=T State1=T State0=T 
PORTA=0x00;
DDRA=0x70;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: 8bit top=FFh
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0H=0x00;
TCNT0L=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=OCR1C
// OC1A output: Discon.
// OC1B output: Discon.
// OC1C output: Discon.
// Fault Protection Mode: Off
// Fault Protection Noise Canceler: Off
// Fault Protection triggered on Falling edge
// Fault Protection triggered by the Analog Comparator: Off
// Dead Time Rising Edge: 0.000 us
// Dead Time Falling Edge: 0.000 us
// Timer1 Overflow Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare D Match Interrupt: Off
// Fault Protection Interrupt: Off
PLLCSR=0x00;

TCCR1A=0x00;
TCCR1B=0x00;
TCCR1C=0x00;
TCCR1D=0x00;
TCCR1E=0x00;
TC1H=0x00;
TCNT1=0x00;
TC1H=0x00;
OCR1A=0x00;
TC1H=0x00;
OCR1B=0x00;
TC1H=0x00;
OCR1C=0x00;
TC1H=0x00;
OCR1D=0x00;
DT1=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7, 12-15: Off
// Interrupt on any change on pins PCINT8-11: Off
MCUCR=0x00;
GIMSK=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Universal Serial Interface initialization
// Mode: Disabled
// Clock source: Register & Counter=no clk.
// USI Counter Overflow Interrupt: Off
USICR=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
ACSRA=0x80;
// Hysterezis level: 0 mV
ACSRB=0x00;

while (1)
  { 
   PORTA.5=0;
   PORTA.6=1;
   PORTA.4=0; 
   for(RESISTANCE = 0; RESISTANCE<=253; RESISTANCE++)		
   {CommandTheResistor(RESISTANCE);
   delay_us(10000);}
   };
}

Изменено пользователем IgorKossak
[codebox] для длинного кода!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы сами то понимаете что Ваша программа должна делать? Что, по Вашему, делает функция CommandTheResistor?

Наводящие вопросы:

1. почему 16 клоков даете? <- этот самый важный

2. что за данные в первых 8 клоках передаются?

3. что за новый способ побитной выдачи числа?

Похоже даташит Вы плохо прочитали.

 

Ну, и по мелочи.

Дайте портам понятные имена, типа так:

#define CS_BIT PORTA.6
#define SCK_BIT PORTA.5
#define SI_BIT PORTA.4

код будет читаться гораздо легче.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Функция CommandTheResistor передаёт резистору 2 байта - командный - где вручную расписана передача каждого бита и бит данных с числом которое отображает устанавливаемое сопротивление его передача записана в цикл. Поэтому всего - 16 клоков(ведь два байта). CommandTheResistor должна обеспечивать передачу клоков через PORTA.5

В первом байте передаются биты от которых зависит какой резистор будет использоватся(для спаренных моделей) и которые разрешают задать сопротивление (всё как описано в даташите)

Для побитной выдачи число(сопротивление) постоянно дилится на 2 и остаток от деления(крайний бит) передаётся резистору. Выходит что число передаётся побитно задом на перед.

Напишите пожалуйста что в программе реализовано неправильно или нерационально? Можно ли передать бит данных и командный бит более просто и не заморачиваясь с задержками и клоками?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Судя из описания на данный потенциометр, данные в нем защелкиваются по положительному фронту тактового импульса. С помощью цикла:

for(i = 0; i<=7; i++)

{ PORTA.5=1;

delay_us(30);

PORTA.4 = R%2;

R=R/2;

delay_us(70);

PORTA.5=0;

delay_us(100);

 

Вы в эту микросхему запишите не то что хотите. Поскольку при положительном фронте тактового сигнала на линии данных будет не то что Вы думаете :).

Решение проблемы следующее: вначале данные, затем синхроимпульс.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...